Skip to content

Feedbacks Resolved: 3 - #41

Merged
dev-rathore merged 18 commits into
masterfrom
dev
Dec 3, 2024
Merged

dev-rathore merged 18 commits into
masterfrom
dev

Conversation

@dev-rathore

@dev-rathore dev-rathore commented Dec 3, 2024 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced tab navigation with updated icons and titles for a clearer user experience.
    • Introduced a new EditCollaborationScreen for editing collaboration details.
    • Added a ProfileIcon component for easier navigation to user profiles.
  • Improvements

    • Streamlined the NotificationsScreen with a new header component.
    • Improved responsiveness in various components using breakpoints.
    • Updated styling for buttons and icons to use FontAwesome for a more modern look.
  • Bug Fixes

    • Fixed layout issues in the ApplicationsTabContent and InvitationsTabContent components to ensure proper display across devices.
  • Chores

    • Updated dependencies and configuration files to support new features and improve performance.

dev-rathore and others added 17 commits November 12, 2024 13:36
* create group bug fix on ios
* carousel for web changes

* crash scenario

* drawer ui improvement
* theme updated and code refactoring
* initial implementation

* updateBytes function added

* made changes for processed and raw attachments
* feedbacks

* resolved feedbacks

* feedbacks

* create collaboration icons

* feedbacks

* empty state for messages screen
* feedbacks resolved
@coderabbitai

coderabbitai Bot commented Dec 3, 2024 •

Copy link
Copy Markdown

Walkthrough

The pull request introduces significant modifications across various components within the application. Key changes include updates to tab icons and titles in the TabLayout, a refactor of the CreateCollaborationScreen, and the introduction of new components such as EditCollaborationScreen. Additionally, various components have been streamlined for better UI representation, including the use of FontAwesomeIcon across several components. The navigation structure has been enhanced with new routes and improved responsiveness, particularly in list components, while styling updates ensure better theme integration.

Changes

File Path Change Summary
app/(main)/(drawer)/(tabs)/_layout.tsx Updated TabLayout component with new tab icons, titles, and tabBarInactiveTintColor property.
app/(modal)/create-collaboration.tsx Refactored CreateCollaborationScreen to render CreateCollaboration component directly.
app/(modal)/edit-collaboration.tsx Introduced new EditCollaborationScreen component for editing collaborations.
app/(public)/pre-signin.tsx Streamlined PreSignIn component by removing unused imports and simplifying button rendering.
app/_layout.tsx Modified screen presentation for collaboration creation and added editing route.
components/BottomSheetActions.tsx Added navigation for editing collaborations in BottomSheetActions.
components/InfluencerCard.tsx Updated icon imports and visual representation of influencer tags.
components/SearchComponent.tsx Refactored imports and styling for the search component.
components/channel/add-modal.tsx Replaced IconButton with Pressable for close functionality in AddModal.
components/channel/channel-list.tsx Enhanced search functionality and added empty state indicator in ChannelList.
components/ui/back-button/BackButton.tsx Replaced Ionicons with FontAwesomeIcon for back button.
components/ui/button/index.tsx Introduced new Button component with customizable styles.
components/ui/button/social-button.tsx Added new SocialButton component for social interactions.
components/ui/modal/DocumentUploadModal.tsx Updated button interactions to use Pressable with FontAwesomeIcon for uploads.
constants/Colors.ts Enhanced theme colors with new properties for card and outline.
contexts/collaboration-context.provider.tsx Added methods for creating and updating collaborations in context.
declare.d.ts Added TypeScript declaration for SVG imports as React components.
metro.config.js Configured Metro bundler to handle SVG files as React components.
package.json Added new dependency for react-native-svg-transformer.
styles/InfluencerCard.styles.tsx Updated styles for loading indicators and theme adaptability.
styles/modal/AddModal.styles.tsx Added color property to modal title style based on theme.

Possibly related PRs

  • Bug fix/UI feedback color changes #20: The changes in app/_layout.tsx involve modifications to the routing logic, which may relate to the navigation structure impacted by the changes in the TabLayout component in the main PR.
  • bug fixes #22: The updates in app/_layout.tsx regarding routing logic could be relevant as they may affect how the tabs and their associated screens are navigated, similar to the changes made in the main PR.
  • Carousel for web #30: The refactoring of the InfluencerCard.tsx component includes updates to media rendering, which may relate to the visual feedback enhancements in the TabLayout component of the main PR, particularly in terms of user interface consistency.

Suggested reviewers

  • Manan-Sharma-5

🐰 In the garden where we play,
Tabs and icons lead the way.
Collaboration now takes flight,
With new screens, oh what a sight!
A hop, a skip, we make it bright,
Join us now, it feels just right! 🌼✨


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.

@dev-rathore dev-rathore self-assigned this Dec 3, 2024
@dev-rathore
dev-rathore merged commit b18b395 into master Dec 3, 2024

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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

🧹 Outside diff range and nitpick comments (49)
components/proposals/Invitations.tsx (2)

Line range hint 52-91: Consider enhancing error handling and type safety

The fetchProposals function could benefit from:

  1. User-facing error notifications instead of just console.error
  2. TypeScript interfaces for the proposal data structure
  3. Error boundary implementation for better error recovery

Would you like me to provide an example implementation with these improvements?


Line range hint 147-153: Fix typo in empty state message

The empty state subtitle contains a typo: "woudl" should be "would"

-            subtitle="Start building your profile today to have better reach. If any brand invites you to collaborate we woudl show it here"
+            subtitle="Start building your profile today to have better reach. If any brand invites you to collaborate we would show it here"
components/collaboration/collaboration-details/OverviewTabContent.tsx (2)

34-35: Consider enhancing the responsive layout implementation

While the current implementation works, it could be improved for better maintainability and user experience:

  1. Move the magic number 768 to a constant or theme variable
  2. Consider using maxWidth instead of fixed width to handle edge cases better
  3. Add a smooth transition to prevent jarring layout shifts

Consider applying this improvement:

+ // At the top of the file with other constants
+ const MAX_CONTENT_WIDTH = 768;

  <ScrollView
    style={{
      flex: 1,
      paddingTop: 8,
      paddingHorizontal: 16,
      paddingBottom: 16,
-     width: xl ? 768 : '100%',
+     maxWidth: MAX_CONTENT_WIDTH,
      marginHorizontal: "auto",
+     transition: 'width 0.3s ease', // Add smooth transition
    }}

Line range hint 1-108: Consider architectural improvements for better maintainability

Several improvements could enhance the component's maintainability and reliability:

  1. Extract repeated Card sections into a reusable component
  2. Remove hardcoded values (e.g., "Instagram" platform)
  3. Add proper error handling for missing collaboration data
  4. Remove unnecessary string concatenation with spaces

Here's a suggested approach for extracting the card component:

interface InfoCardProps {
  title: string;
  content: React.ReactNode;
  image?: string;
}

const InfoCard: React.FC<InfoCardProps> = ({ title, content, image }) => (
  <Card style={styles.infoCard}>
    {image && <Image source={{ uri: image }} style={styles.profileImage} />}
    <View>
      <Text variant="headlineSmall" style={styles.cardName}>{title}</Text>
    </View>
    <Card.Content>{content}</Card.Content>
  </Card>
);

// Usage in main component:
<InfoCard
  title="Platform"
  content={<Paragraph style={styles.paragraph}>{collaboration.platform}</Paragraph>}
/>

Also, consider adding null checks:

- Cost: {collaboration.budget.min}
+ Cost: {collaboration?.budget?.min ?? 'N/A'}
components/drawer-layout/BrandActionItem.tsx (1)

50-57: Consider these refinements for better maintainability

The FontAwesome implementation looks good, but there are a few potential improvements:

  1. Move the margin style to the styles object:
-style={{
-  marginRight: 6,
-  backgroundColor: Colors(theme).transparent,
-}}
+style={[
+  styles.icon,
+  { backgroundColor: Colors(theme).transparent }
+]}

Add to stylesFn:

icon: {
  marginRight: 6,
}
  1. Simplify the color prop using a ternary:
-color={active ? Colors(theme).white : Colors(theme).text}
+color={Colors(theme)[active ? 'white' : 'text']}

Also applies to: 74-77

components/explore-influencers/header.tsx (2)

12-18: Remove unused props parameter and consider modern TypeScript practices

The component declares props but doesn't use them. Also, the React.FC type annotation is redundant with modern TypeScript.

-const Header: React.FC = (props) => {
+const Header = () => {

21-36: Consider extracting styles for better maintainability

The inline styles could be moved to a separate styles object or a styled-components implementation for better reusability and maintainability.

+const styles = {
+  container: {
+    display: "flex",
+    flexDirection: "row",
+    alignItems: "center",
+  },
+  brandText: {
+    fontSize: 24,
+    fontWeight: "bold",
+  }
+};

-<View
-  style={{
-    display: "flex",
-    flexDirection: "row",
-    alignItems: "center",
-  }}
->
+<View style={styles.container}>
   <Text
-    style={{
-      color: Colors(theme).text,
-      fontSize: 24,
-      fontWeight: "bold",
-    }}
+    style={[styles.brandText, { color: Colors(theme).text }]}
   >
components/explore-influencers/index.tsx (2)

93-94: Document theme-dependent padding behavior

The padding changes based on both breakpoint and theme. Consider adding a comment explaining why dark theme requires additional padding.

 style={{
   paddingHorizontal: xl ? 0 : 16,
+  // Additional padding needed in dark theme to separate search component from content
   paddingBottom: theme.dark ? 16 : 0,
 }}

103-106: Extract magic number to constants

The fixed width value (768) should be moved to a constants file for better maintainability.

+// In constants/Layout.ts
+export const CONTENT_MAX_WIDTH = 768;

-style={{
-  width: xl ? 768 : '100%',
-  marginHorizontal: "auto",
-}}
+style={{
+  width: xl ? CONTENT_MAX_WIDTH : '100%',
+  marginHorizontal: "auto",
+}}
components/collaboration/collaboration-details/ApplicationsTabContent.tsx (2)

15-15: Consider using TypeScript properly for better type safety

The useBreakpoints hook implementation looks good, but the component props are typed as any. Consider defining proper interface for the props.

interface ApplicationsTabContentProps {
  pageID: string;
  collaboration: {
    // Add relevant collaboration properties
  };
}

Also applies to: 24-26


126-127: Consider extracting magic numbers into constants

The hardcoded width value of 768 should be extracted into a constant or theme variable for better maintainability.

+ const DESKTOP_WIDTH = 768;
// ...
- width: xl ? 768 : '100%',
+ width: xl ? DESKTOP_WIDTH : '100%',
components/collaboration/collaboration-details/InvitationsTabContent.tsx (2)

Line range hint 52-75: Improve error handling in handleCollaborationInvite

The current error handling only logs to console and shows a generic message. Consider handling specific error cases.

 try {
   // ... existing code ...
 } catch (error) {
-  console.error(error);
-  Toaster.error("Failed to send invitation");
+  if (error instanceof Error) {
+    console.error('Invitation error:', error.message);
+    Toaster.error(
+      error.message.includes('permission-denied')
+        ? "You don't have permission to send invitations"
+        : "Failed to send invitation"
+    );
+  }
 }

Line range hint 178-220: Consider extracting the invitation modal into a separate component

The modal logic and UI could be moved to a separate component to improve maintainability and reusability.

interface InvitationModalProps {
  visible: boolean;
  onClose: () => void;
  onSubmit: (message: string) => Promise<void>;
  isLoading: boolean;
}

const InvitationModal: React.FC<InvitationModalProps> = ({
  visible,
  onClose,
  onSubmit,
  isLoading,
}) => {
  // ... modal implementation
};
components/proposals/Applications.tsx (2)

Line range hint 54-121: Consider extracting data fetching logic into a custom hook

The proposal fetching logic is complex and could be reused. Consider moving it to a custom hook.

const useProposals = (brandId: string) => {
  const [proposals, setProposals] = useState<Proposal[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  
  const fetchProposals = useCallback(async () => {
    // ... existing fetch logic
  }, [brandId]);

  useEffect(() => {
    fetchProposals();
  }, [fetchProposals]);

  return { proposals, isLoading, refetch: fetchProposals };
};

Line range hint 164-186: Consider reducing prop drilling in JobCard

The JobCard component receives many individual props. Consider passing a structured object instead.

interface JobCardProps {
  collaboration: {
    name: string;
    id: string;
    brandName: string;
    // ... other properties
  };
  onOpenBottomSheet: (id: string) => void;
}
components/create-collaboration/screen-two.tsx (1)

126-126: Avoid using index as a key when rendering lists

Using the index as part of the key can cause issues if the list items change order or are modified. It's better to use a unique identifier from the data.

Update the key to use a unique property like link.url:

- <Paragraph key={index + link.url}>
+ <Paragraph key={link.url}>
styles/searchbar/Searchbar.styles.tsx (1)

6-12: Consider adding accessibility-friendly dimensions

While the current dimensions work, consider adjusting the height to meet minimum touch target sizes for better accessibility:

  • Minimum height should be 44px for touch targets
  • Consider adding proper padding for better touch areas
 searchbar: {
   flex: 1,
   fontSize: 16,
   borderRadius: 10,
-  height: 40,
+  height: 44,
+  paddingHorizontal: 12,
   backgroundColor: Colors(theme).aliceBlue,
 },
components/ui/button/index.tsx (2)

7-9: Enhance type safety for animated styles

The customStyles type could be more specific to ensure proper animated values are passed.

 interface ButtonProps extends RNPButtonProps {
-  customStyles?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
+  customStyles?: Animated.AnimatedProps<StyleProp<ViewStyle>> | StyleProp<ViewStyle>;
 }

11-24: Consider making the button mode configurable

The button mode is hardcoded to "contained". Consider making it configurable while keeping "contained" as the default.

 const Button: React.FC<ButtonProps> = ({
   customStyles,
+  mode = "contained",
   ...props
 }) => {
   return (
     <RNPButton
-      mode="contained"
+      mode={mode}
       style={[customStyles]}
       {...props}
     />
   );
 };
components/drawer-layout/DrawerIcon.tsx (3)

7-10: Consider extending props interface

The interface could be more flexible by adding a size prop with a default value.

 interface DrawerIconProps {
   href?: string;
   icon: IconProp;
+  size?: number;
 }

22-26: Improve color logic maintainability

The color logic could be simplified and made more maintainable.

-      color={
-        href?.includes(pathname)
-          ? Colors(theme).white
-          : Colors(theme).text
-      }
+      color={Colors(theme)[href?.includes(pathname) ? 'white' : 'text']}

27-27: Consider making icon size configurable

The hardcoded size of 28 should be made configurable with a default value.

-      size={28}
+      size={size ?? 28}
styles/button/Button.styles.tsx (1)

14-21: Consider platform-specific shadow implementations

The current shadow implementation might render differently across platforms. Consider using platform-specific shadow implementations for consistent appearance.

 shadowColor: Colors(theme).black,
-shadowOffset: {
-  width: 0,
-  height: 2,
-},
-shadowOpacity: 0.25,
-shadowRadius: 3.84,
-elevation: 5,
+...Platform.select({
+  ios: {
+    shadowOffset: {
+      width: 0,
+      height: 2,
+    },
+    shadowOpacity: 0.25,
+    shadowRadius: 3.84,
+  },
+  android: {
+    elevation: 5,
+  },
+}),
styles/modal/AddModal.styles.tsx (1)

Line range hint 26-35: Consider adding accessibility properties

For better accessibility, consider adding accessibilityRole and accessibilityLabel styles to complement the modal title styling.

 modalTitle: {
   paddingTop: 15,
   textAlign: "center",
   fontSize: 20,
   fontWeight: "bold",
   color: Colors(theme).gray100,
+  accessibilityRole: "header",
 },
components/ui/back-button/BackButton.tsx (1)

Line range hint 20-42: Remove redundant Pressable wrapper

The component has nested Pressable components with the same onPress handler, which is unnecessary and could lead to event bubbling.

Suggested fix:

  return (
    <Pressable
      onPress={() => navigation.goBack()}
+     style={{
+       display: "flex",
+       justifyContent: "center",
+       alignItems: "center",
+     }}
    >
-     <View
-       style={{
-         display: "flex",
-         justifyContent: "center",
-         alignItems: "center",
-       }}
-     >
-       <Pressable
-         onPress={() => navigation.goBack()}
-       >
-         {({ pressed }) => (
            <FontAwesomeIcon
              icon={faArrowLeft}
              size={20}
              color={color ?? Colors(theme).text}
              style={{
                opacity: pressed ? 0.8 : 1,
              }}
            />
-         )}
-       </Pressable>
-     </View>
    </Pressable>
  );
styles/tab1.styles.tsx (1)

15-15: Consider extracting style constants

Common values like spacing and font sizes should be extracted to a constants file for better maintainability and consistency.

Create a new file constants/Layout.ts:

export const spacing = {
  xs: 8,
  sm: 16,
  md: 20,
  lg: 24,
  xl: 30,
};

export const typography = {
  title: 24,
  body: 16,
};

Then update the styles:

- paddingHorizontal: 16,
+ paddingHorizontal: spacing.sm,

- fontSize: 24,
+ fontSize: typography.title,

- fontSize: 16,
+ fontSize: typography.body,

Also applies to: 39-39

components/create-collaboration/screen-three.tsx (1)

22-35: Consider adding accessibility attributes.

While the implementation looks good, consider enhancing accessibility for screen readers.

 <View style={styles.container3}>
   <FontAwesomeIcon
     icon={faCheckCircle}
     size={100}
     color={Colors(theme).primary}
     style={styles.checkIcon}
+    accessibilityRole="image"
+    accessibilityLabel="Success check mark"
   />
   <Title 
     style={styles.title}
+    accessibilityRole="header"
   >
     Collaboration {type === "Add" ? "Posted" : "Updated"}
   </Title>
   <Text 
     style={styles.description}
+    accessibilityRole="text"
   >
     Your collaboration has been successfully {type === "Add" ? "posted" : "updated"}.
   </Text>
 </View>
constants/Colors.ts (1)

Line range hint 1-58: Consider documenting color semantic usage.

The color system is growing. Consider adding JSDoc comments to document the semantic usage of each color token.

 export default (theme: Theme) => ({
   ...theme.colors,
   ...(theme.dark
     ? {
+        /** Used for card backgrounds in dark mode */
         card: "#1E1E1E",
+        /** Used for component outlines and borders */
         outline: "#538BA6",
         // ... add similar documentation for other colors
components/drawer-layout/DrawerMenuItem.tsx (1)

44-48: Consider memoizing icon rendering for performance

The icon rendering could benefit from memoization to prevent unnecessary re-renders.

+ const iconElement = React.useMemo(() => 
+   tab.icon({
+     focused: tab.href.includes(pathname),
+   }),
+   [tab.icon, pathname]
+ );

  return (
    <Pressable onPress={() => router.push(tab.href)}>
      <View style={{...}}>
-       {tab.icon({
-         focused: tab.href.includes(pathname),
-       })}
+       {iconElement}
components/ui/screen-header/index.tsx (3)

Line range hint 27-33: Memoize handleAction function

The handleAction function is recreated on every render but its dependencies are stable.

- const handleAction = () => {
+ const handleAction = React.useCallback(() => {
    if (action) {
      action();
    } else {
      navigation.goBack();
    }
-  }
+  }, [action, navigation]);

73-73: Simplify rightAction rendering condition

The current condition could be simplified and made more explicit.

- {rightAction && rightActionButton}
+ {rightActionButton && rightAction ? rightActionButton : null}

43-65: Extract icon styles to constants

Consider extracting the repeated style objects to constants for better maintainability.

+ const styles = {
+   iconContainer: {
+     marginTop: 2,
+   },
+   icon: {
+     size: 20,
+   },
+ };

  {!hideAction && (
    <Appbar.Action
      icon={() => (
        <View
-         style={{
-           marginTop: 2,
-         }}
+         style={styles.iconContainer}
          lightColor={Colors(theme).transparent}
          darkColor={Colors(theme).transparent}
        >
          <FontAwesomeIcon
            icon={faArrowLeft}
-           size={20}
+           size={styles.icon.size}
            color={Colors(theme).text}
          />
        </View>
      )}
      color={Colors(theme).text}
      onPress={handleAction}
    />
  )}
components/ui/brand-switcher/index.tsx (1)

Line range hint 42-48: Optimize icon styling properties

While the icon change to faChevronDown is a good choice for dropdown indication, there's redundancy in the color definition:

 <FontAwesomeIcon
-  color={Colors(theme).text}
   icon={faChevronDown}
   size={24}
   style={{
     marginLeft: 14,
-    color: Colors(theme).text,
     marginBottom: -2,
   }}
 />

Also, consider using proper vertical alignment instead of negative margin:

   style={{
     marginLeft: 14,
-    marginBottom: -2,
+    alignSelf: 'center'
   }}
contexts/collaboration-context.provider.tsx (2)

16-21: Consider implementing data validation and sanitization

The interface implementation should include input validation before storage:

Consider implementing a validation layer:

  1. Create a validation schema for ICollaboration
  2. Add input sanitization
  3. Implement type guards

Example implementation:

import { z } from 'zod';

const CollaborationSchema = z.object({
  // define your schema here
});

function validateCollaboration(data: unknown): ICollaboration {
  return CollaborationSchema.parse(data);
}

62-63: Consider implementing optimistic updates

The context could benefit from optimistic updates to improve UX:

  1. Update local state immediately
  2. Revert on error
  3. Implement proper loading states

This would make the UI feel more responsive while maintaining data integrity.

components/SearchComponent.tsx (1)

38-44: Consider memoizing the icon render function

The icon render function is recreated on every render. Consider memoizing it using useCallback to optimize performance.

+ const renderSearchIcon = useCallback(() => (
+   <FontAwesomeIcon
+     color={Colors(theme).gray100}
+     icon={faMagnifyingGlass}
+     size={18}
+   />
+ ), [theme]);

  return (
    <View style={[searchComponentStyles.searchContainer]}>
      <Searchbar
-       icon={() => (
-         <FontAwesomeIcon
-           color={Colors(theme).gray100}
-           icon={faMagnifyingGlass}
-           size={18}
-         />
-       )}
+       icon={renderSearchIcon}
components/channel/channel.tsx (1)

49-60: Consider extracting the add member button to a separate component

The add member button logic could be extracted to improve readability and reusability. Also, consider adding accessibility attributes.

+ const AddMemberButton: React.FC<{ onPress: () => void }> = ({ onPress }) => {
+   const theme = useTheme();
+   return (
+     <Pressable
+       onPress={onPress}
+       accessibilityRole="button"
+       accessibilityLabel="Add member"
+     >
+       <FontAwesomeIcon
+         icon={faPlus}
+         size={20}
+         color={Colors(theme).text}
+       />
+     </Pressable>
+   );
+ };

  <ScreenHeader
    title={channel?.data?.name || 'Chat'}
    rightAction
-   rightActionButton={
-     <Pressable
-       onPress={() => setModalVisible(true)}
-     >
-       <FontAwesomeIcon
-         icon={faPlus}
-         size={20}
-         color={Colors(theme).text}
-       />
-     </Pressable>
-   }
+   rightActionButton={
+     <AddMemberButton onPress={() => setModalVisible(true)} />
+   }
  />
components/collaboration/CollaborationHeader.tsx (1)

48-54: Consider optimizing icon render functions

While the FontAwesome icon implementation looks good, we can optimize performance by memoizing the icon render functions or moving them outside the component to prevent unnecessary re-renders.

Consider this optimization:

+ const renderBoltIcon = (theme: Theme) => (
+   <FontAwesomeIcon
+     color={Colors(theme).primary}
+     icon={faBolt}
+     size={14}
+   />
+ );

+ const renderEyeIcon = (theme: Theme) => (
+   <FontAwesomeIcon
+     color={Colors(theme).primary}
+     icon={faEye}
+     size={14}
+   />
+ );

+ const renderLocationIcon = (theme: Theme) => (
+   <FontAwesomeIcon
+     color={Colors(theme).primary}
+     icon={faLocationDot}
+     size={14}
+   />
+ );

  const CollaborationHeader: React.FC<ColloborationHeaderProps> = ({
    collaboration,
  }) => {
    const theme = useTheme();
    const styles = stylesFn(theme);

    return (
      // ...
-     icon={() => (
-       <FontAwesomeIcon
-         color={Colors(theme).primary}
-         icon={faBolt}
-         size={14}
-       />
-     )}
+     icon={() => renderBoltIcon(theme)}
      // ... Apply similar changes for other icons
    );
  };

Also applies to: 63-69, 76-82

components/ui/carousel/render-media-item.tsx (1)

42-42: LGTM: Loading state management for images

The addition of loading state and ActivityIndicator improves user experience by providing visual feedback during image loading.

Consider adding error handling:

 <Image
   source={imageUrl(item.url)}
   style={[styles.media, ...]}
   resizeMode="stretch"
   onLoadStart={() => setIsLoading(true)}
   onLoad={() => setIsLoading(false)}
+  onError={() => {
+    setIsLoading(false);
+    console.error('Image loading failed:', item.url);
+  }}
 />

Also applies to: 58-67, 78-79

components/ui/modal/ImageUploadModal.tsx (1)

Line range hint 27-45: Consider sharing permission handling logic

The permission handling logic here is well implemented. Consider extracting it into a shared utility to maintain consistency across both upload modals.

Create a shared utility:

// utils/permissions.ts
export const requestMediaPermission = async () => {
  const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
  if (status !== 'granted') {
    Alert.alert(
      'Permission Required',
      'Please grant permissions from settings',
      [
        { text: 'Cancel', style: 'cancel' },
        { text: 'Open Settings', onPress: () => Linking.openSettings() },
      ]
    );
    return false;
  }
  return true;
};
components/ui/select/index.tsx (1)

56-70: Consider extracting style objects

The inline styles could be moved outside the component for better readability and performance.

+const getContainerStyle = (direction: "row" | "column") => ({
+  flex: 1,
+  gap: 8,
+  ...(direction === "row" 
+    ? { flexDirection: "row", flexWrap: "wrap" }
+    : { flexDirection: "column", justifyContent: "center" })
+});

 return (
   <View
     style={[
-      {
-        flex: 1,
-        gap: 8,
-      },
-      direction === "row" ? {
-        flexDirection: "row",
-        flexWrap: "wrap",
-      } : {
-        flexDirection: "column",
-        justifyContent: "center",
-      },
+      getContainerStyle(direction),
       style,
     ]}
   >
app/(public)/pre-signin.tsx (2)

Line range hint 25-35: Consider memoizing the skipToConnect function

The skipToConnect function could be memoized since it depends only on the static slides array.

+import { useCallback } from 'react';

-const skipToConnect = () => {
+const skipToConnect = useCallback(() => {
   const connectSlideIndex = slides.findIndex(
     (slide) => slide.key === "connect"
   );
   if (connectSlideIndex !== -1) {
     swiperRef.current?.scrollBy(connectSlideIndex);
   }
-};
+}, []);

97-97: Enhance error handling presentation

The error message could benefit from a more structured presentation using a dedicated error component.

-{error && <Text style={{ color: "red" }}>Error: {error}</Text>}
+{error && (
+  <View style={styles.errorContainer}>
+    <Text style={styles.errorText}>Error: {error}</Text>
+  </View>
+)}
components/channel/channel-list.tsx (1)

82-98: Consider adding loading state handling

While the empty state implementation looks good, consider handling the loading state to prevent flashing of the empty state during initial data fetch.

 <ChannelList
+  LoadingIndicator={() => (
+    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
+      <ActivityIndicator size="large" color={Colors(theme).primary} />
+    </View>
+  )}
   EmptyStateIndicator={() => (
     // ... existing code
   )}
components/menu/index.tsx (1)

114-119: Add hover and active states for better interaction feedback

The chevron icon could benefit from hover and active states for better user interaction feedback.

 <Pressable
+ style={({ pressed }) => [
+   styles.userProfileContainer,
+   pressed && { opacity: 0.7 }
+ ]}
  onPress={() => {
    router.push("/profile");
  }}
 >
app/(main)/(drawer)/(tabs)/_layout.tsx (1)

53-73: Consider memoizing the header component

The header component is recreated on each render. Consider memoizing it for better performance.

+ const MemoizedHeader = React.memo(Header);
+
 const TabLayout = () => {
   // ... existing code
   headerTitle() {
     return (
-      <Header />
+      <MemoizedHeader />
     )
   },
components/drawer-layout/DrawerMenuContent.tsx (1)

34-35: Simplify empty interface declaration

The empty interface can be simplified to a type alias.

-interface DrawerMenuContentProps { }
+type DrawerMenuContentProps = Record<string, never>;
🧰 Tools
🪛 Biome (1.9.4)

[error] 34-35: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

components/create-collaboration/screen-one.tsx (1)

84-84: Remove commented code

Remove the commented multiline prop or implement it if needed for better user input experience.

components/BottomSheetActions.tsx (1)

Line range hint 19-26: Consider improving type safety for cardId

The cardId prop is currently typed as any, which could lead to runtime errors. Consider creating a proper type definition.

interface BottomSheetActionsProps {
  cardType:
    | "influencerType"
    | "promotionType"
    | "influencerCard"
    | "applicationCard"
    | "invitationCard"
    | "activeCollab";
  data?: any; // TODO: Update with the correct type
-  cardId?: any;
+  cardId?: string | { collaborationID: string; applicationID: string; influencerID: string };
  isVisible: boolean;
  snapPointsRange: [string, string];
  onClose: () => void;
}
🛑 Comments failed to post (22)
components/drawer-layout/BrandActionItem.tsx (1)

6-8: 💡 Codebase verification

Mixed icon library usage detected in onboarding screens

The migration to FontAwesome icons is mostly consistent across the codebase, but there are three instances in the onboarding flow that still use react-native-paper's IconButton with icon names:

  • app/(onboarding)/onboarding-your-brand.tsx: Uses IconButton with "arrow-left" icon
  • app/(onboarding)/onboarding-brand-preference.tsx: Uses IconButton with "information-outline" icon in two places

These should be migrated to FontAwesome icons for consistency with the rest of the application.

🔗 Analysis chain

Verify consistent icon library usage across the codebase

The migration from react-native-paper icons to FontAwesome icons looks good and provides better type safety with IconProp. However, we should ensure this change is consistent across all components.

Also applies to: 12-12


Let me analyze the results. I can see that:

  1. There are no Avatar.Icon usages in the codebase
  2. There are only two files still using IconButton from react-native-paper, both in the onboarding flow
  3. FontAwesomeIcon is widely used across the codebase (29 files)

Let me verify if the IconButton usage in those onboarding files actually uses icons:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for mixed usage of icon libraries
# Look for components still using react-native-paper icons

# Check for Avatar.Icon usage
rg "Avatar\.Icon"

# Check for IconButton usage from react-native-paper
rg "IconButton.*from.*react-native-paper"

# Check for consistent FontAwesome imports
rg "import.*FontAwesomeIcon"

Length of output: 3595


Script:

#!/bin/bash
# Check the context of IconButton usage in onboarding files
rg -B 2 -A 2 "IconButton" "app/(onboarding)/onboarding-brand-preference.tsx" "app/(onboarding)/onboarding-your-brand.tsx"

Length of output: 2345

components/explore-influencers/header.tsx (1)

37-57: ⚠️ Potential issue

Add onPress handler and improve icon positioning

The Pressable component lacks an onPress handler, and the icon positioning uses fragile negative margins.

-<Pressable>
+<Pressable onPress={() => xl ? undefined : toggleDrawer()}>
   {
     xl ? (
       <BrandSwitcher />
     ) : (
       <DrawerToggleButton
         icon={
           <FontAwesomeIcon
             color={Colors(theme).text}
             icon={faChevronDown}
             size={16}
             style={{
-              marginLeft: 6,
-              marginBottom: -2,
+              marginLeft: 6,
+              transform: [{ translateY: 1 }]
             }}
           />
         }
       />
     )
   }
 </Pressable>

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

components/create-collaboration/screen-two.tsx (1)

17-17: 🛠️ Refactor suggestion

Define a specific type for the links array

Using any[] for the links array can lead to type safety issues. Defining a specific interface for the links enhances type safety and code maintainability.

For example, define a Link interface:

interface Link {
  name: string;
  url: string;
}

Then update the types:

// In ScreenTwoProps (line 17)
- links: any[];
+ links: Link[];

// In setState (line 29)
- links: React.Dispatch<React.SetStateAction<any[]>>;
+ links: React.Dispatch<React.SetStateAction<Link[]>>;

Also applies to: 29-29

components/create-collaboration/index.tsx (2)

147-149: ⚠️ Potential issue

Prevent execution when the user is not authenticated

After logging "User not logged in", the function should return to prevent further execution, which could lead to errors or unintended behavior.

Apply this diff to fix the issue:

if (!AuthApp.currentUser) {
  console.error("User not logged in");
+ 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.

      if (!AuthApp.currentUser) {
        console.error("User not logged in");
        return;
      }

151-160: ⚠️ Potential issue

Ensure selection arrays are not empty

When validating required fields, check that promotionType, collabType, and platform arrays are not empty to confirm that selections have been made.

Update the validation logic:

if (
  !collaborationName ||
  !aboutCollab ||
  !budgetMin ||
  !budgetMax ||
- !promotionType ||
- !collabType ||
  !numInfluencers ||
- !platform ||
  !location
) {
  Toaster.error("Please fill all fields");
  return;
}
+ if (
+   promotionType.length === 0 ||
+   collabType.length === 0 ||
+   platform.length === 0
+ ) {
+   Toaster.error("Please select options for Promotion Type, Collaboration Type, and Platform");
+   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.

      if (
        !collaborationName ||
        !aboutCollab ||
        !budgetMin ||
        !budgetMax ||
        !numInfluencers ||
        !location
      ) {
        Toaster.error("Please fill all fields");
        return;
      }
      if (
        promotionType.length === 0 ||
        collabType.length === 0 ||
        platform.length === 0
      ) {
        Toaster.error("Please select options for Promotion Type, Collaboration Type, and Platform");
        return;
      }
components/ui/button/index.tsx (1)

18-20: 🛠️ Refactor suggestion

Consider adding base styles and handling style precedence

The style array only includes customStyles without any base styles. Also, spreading props after style could lead to style overrides.

 <RNPButton
   mode="contained"
   style={[
+    styles.base,
     customStyles,
+    props.style,
   ]}
-  {...props}
+  {...omit(props, ['style'])}
 />

Consider creating a base style object and using a utility like omit to prevent style prop conflicts.

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

components/ui/button/social-button.tsx (2)

9-13: 🛠️ Refactor suggestion

Add loading state and accessibility props

For social authentication buttons, it's important to handle loading states and provide proper accessibility support.

Extend the props interface:

 interface SocialButtonProps extends PressableProps {
   customStyles?: StyleProp<ViewStyle>;
   icon: IconProp;
   label: string;
+  loading?: boolean;
+  accessibilityLabel?: string;
 }
📝 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.

interface SocialButtonProps extends PressableProps {
  customStyles?: StyleProp<ViewStyle>;
  icon: IconProp;
  label: string;
  loading?: boolean;
  accessibilityLabel?: string;
}

24-39: 🛠️ Refactor suggestion

Enhance button accessibility and loading state handling

The button should handle loading states and provide proper accessibility information.

Suggested implementation:

   return (
     <Pressable
       style={[
         styles.socialButton,
         customStyles,
       ]}
+      disabled={loading}
+      accessibilityRole="button"
+      accessibilityLabel={accessibilityLabel || `Sign in with ${label}`}
+      accessibilityState={{ disabled: loading }}
       {...props}
     >
+      {loading ? (
+        <ActivityIndicator size="small" color={Colors(theme).text} />
+      ) : (
         <FontAwesomeIcon
           icon={icon}
           size={24}
           color={Colors(theme).text}
           style={styles.socialButtonIcon}
         />
+      )}
       <Text style={styles.socialButtonText}>{label}</Text>
     </Pressable>
   );

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

components/ui/drawer-toggle-button/DrawerToggleButton.tsx (1)

35-42: 🛠️ Refactor suggestion

Ensure adequate touch target size for accessibility.

While the icon implementation looks good, the touch target might be too small for comfortable interaction.

 <FontAwesomeIcon
   color={Colors(theme).text}
   icon={faBars}
   size={24}
   style={{
     marginLeft: 14,
-    marginBottom: -2,
+    padding: 8,  // Add padding to increase touch target
   }}
+  accessibilityRole="button"
+  accessibilityLabel="Open drawer menu"
 />
📝 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.

            <FontAwesomeIcon
              color={Colors(theme).text}
              icon={faBars}
              size={24}
              style={{
                marginLeft: 14,
                padding: 8,
              }}
              accessibilityRole="button"
              accessibilityLabel="Open drawer menu"
components/explore-influencers/profile-icon.tsx (2)

42-49: ⚠️ Potential issue

Add error handling for image loading

The image source doesn't handle potential null/undefined cases from selectedBrand?.image, which could lead to runtime errors.

+ const imageSource = React.useMemo(() => {
+   if (!selectedBrand?.image) {
+     return require('@/assets/images/default-profile.png');
+   }
+   return imageUrl(selectedBrand.image);
+ }, [selectedBrand?.image]);

  <Image
-   source={imageUrl(selectedBrand?.image)}
+   source={imageSource}
+   onError={(e) => console.warn('Profile image loading failed:', e.nativeEvent.error)}
    style={{
      borderRadius: 100,
      height: 28,
      width: 28,
    }}
  />
📝 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.

            const imageSource = React.useMemo(() => {
              if (!selectedBrand?.image) {
                return require('@/assets/images/default-profile.png');
              }
              return imageUrl(selectedBrand.image);
            }, [selectedBrand?.image]);

            <Image
              source={imageSource}
              onError={(e) => console.warn('Profile image loading failed:', e.nativeEvent.error)}
              style={{
                borderRadius: 100,
                height: 28,
                width: 28,
              }}
            />

19-52: 🛠️ Refactor suggestion

Add accessibility support

The profile icon button lacks accessibility props, making it difficult for screen readers.

  <Link href="/menu" asChild>
-   <Pressable>
+   <Pressable
+     accessible={true}
+     accessibilityRole="button"
+     accessibilityLabel="Open menu"
+     accessibilityHint="Opens the profile menu">
📝 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.

    <Link href="/menu" asChild>
      <Pressable
        accessible={true}
        accessibilityRole="button"
        accessibilityLabel="Open menu"
        accessibilityHint="Opens the profile menu">
        {({ pressed }) => (
          <View
            style={{
              position: "relative",
              marginRight: 15,
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <FontAwesomeIcon
              color={Colors(theme).primary}
              icon={faCircleNotch}
              size={32}
              style={{
                left: -2,
                opacity: pressed ? 0.5 : 1,
                position: "absolute",
                top: -2,
                zIndex: 1,
              }}
            />
            <Image
              source={imageUrl(selectedBrand?.image)}
              style={{
                borderRadius: 100,
                height: 28,
                width: 28,
              }}
            />
          </View>
        )}
      </Pressable>
components/channel/add-modal.tsx (1)

52-61: 🛠️ Refactor suggestion

Enhance close button accessibility

While the close button implementation is clean, consider adding accessibility props:

 <Pressable
   onPress={() => setVisible(false)}
   style={styles.closeButton}
+  accessibilityRole="button"
+  accessibilityLabel="Close modal"
 >
   <FontAwesomeIcon
     icon={faClose}
     size={20}
     color={Colors(theme).gray100}
   />
 </Pressable>
📝 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.

            <Pressable
              onPress={() => setVisible(false)}
              style={styles.closeButton}
              accessibilityRole="button"
              accessibilityLabel="Close modal"
            >
              <FontAwesomeIcon
                icon={faClose}
                size={20}
                color={Colors(theme).gray100}
              />
            </Pressable>
contexts/collaboration-context.provider.tsx (2)

49-56: ⚠️ Potential issue

Add error handling and input validation

The updateCollaboration method needs error handling and input validation:

 const updateCollaboration = async (
   id: string,
   collaboration: Partial<ICollaboration>,
 ): Promise<void> => {
+  if (!id?.trim()) {
+    throw new Error('Invalid collaboration ID');
+  }
+
+  try {
     const collaborationRef = doc(FirestoreDB, "collaborations", id);
     await updateDoc(collaborationRef, collaboration);
+  } catch (error) {
+    console.error('Failed to update collaboration:', error);
+    throw new Error('Failed to update collaboration. Please try again.');
+  }
 }
📝 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.

  const updateCollaboration = async (
    id: string,
    collaboration: Partial<ICollaboration>,
  ): Promise<void> => {
    if (!id?.trim()) {
      throw new Error('Invalid collaboration ID');
    }

    try {
      const collaborationRef = doc(FirestoreDB, "collaborations", id);
      await updateDoc(collaborationRef, collaboration);
    } catch (error) {
      console.error('Failed to update collaboration:', error);
      throw new Error('Failed to update collaboration. Please try again.');
    }
  }

42-47: ⚠️ Potential issue

Add error handling for Firestore operations

The createCollaboration method should include error handling:

 const createCollaboration = async (
   collaboration: ICollaboration,
 ): Promise<void> => {
+  try {
     const collaborationRef = collection(FirestoreDB, "collaborations");
     await addDoc(collaborationRef, collaboration);
+  } catch (error) {
+    console.error('Failed to create collaboration:', error);
+    throw new Error('Failed to create collaboration. Please try again.');
+  }
 }
📝 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.

  const createCollaboration = async (
    collaboration: ICollaboration,
  ): Promise<void> => {
    try {
      const collaborationRef = collection(FirestoreDB, "collaborations");
      await addDoc(collaborationRef, collaboration);
    } catch (error) {
      console.error('Failed to create collaboration:', error);
      throw new Error('Failed to create collaboration. Please try again.');
    }
  }
components/ui/modal/DocumentUploadModal.tsx (1)

82-90: 🛠️ Refactor suggestion

Add accessibility and visual feedback to upload buttons

While the switch to Pressable components is good, they're missing important properties for accessibility and user feedback.

Add accessibility and visual feedback:

 <Pressable
   onPress={openGallery}
   style={styles.modalButton}
+  accessibilityRole="button"
+  accessibilityLabel="Upload image from gallery"
+  android_ripple={{ color: 'rgba(0, 0, 0, 0.1)' }}
+  style={({ pressed }) => [
+    styles.modalButton,
+    pressed && { opacity: 0.7 }
+  ]}
 >
   <FontAwesomeIcon
     icon={faImage}
     size={20}
   />
 </Pressable>

Apply similar changes to the document upload button as well.

Also applies to: 91-99

components/ui/modal/ImageUploadModal.tsx (1)

93-101: 🛠️ Refactor suggestion

Maintain consistency with DocumentUploadModal

While the error handling is good, the Pressable components need the same accessibility improvements as DocumentUploadModal.

Add accessibility and visual feedback:

 <Pressable
   onPress={openCamera}
   style={styles.modalButton}
+  accessibilityRole="button"
+  accessibilityLabel="Take photo with camera"
+  android_ripple={{ color: 'rgba(0, 0, 0, 0.1)' }}
+  style={({ pressed }) => [
+    styles.modalButton,
+    pressed && { opacity: 0.7 }
+  ]}
 >
   <FontAwesomeIcon
     icon={faCamera}
     size={20}
   />
 </Pressable>

Apply similar changes to the gallery upload button as well.

Also applies to: 102-110

components/ui/select/index.tsx (1)

75-79: ⚠️ Potential issue

Remove duplicate key prop

The key prop is unnecessarily duplicated on both the Pressable and inner View components. The outer key is sufficient for React's reconciliation.

 <Pressable
   key={item.value}
   onPress={() => handleSelect(item)}
 >
   <View
-    key={item.value}
     style={[

Also applies to: 80-80

components/channel/channel-list.tsx (1)

107-123: 🛠️ Refactor suggestion

Add accessibility attributes to Pressable

The add group button should have accessibility attributes for better screen reader support.

 <Pressable
+ accessibilityLabel="Add new group"
+ accessibilityRole="button"
  onPress={() => setModalVisible(true)}
  style={{
📝 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.

      <Pressable
        accessibilityLabel="Add new group"
        accessibilityRole="button"
        onPress={() => setModalVisible(true)}
        style={{
          position: "absolute",
          right: 10,
          bottom: 10,
          backgroundColor: Colors(theme).aliceBlue,
          padding: 10,
          borderRadius: 10,
        }}
      >
        <FontAwesomeIcon
          color={Colors(theme).gray100}
          icon={faPlus}
          size={20}
        />
      </Pressable>
app/(main)/(drawer)/(tabs)/_layout.tsx (1)

107-109: 🛠️ Refactor suggestion

Add error handling for navigation

Consider adding error handling for the navigation action to handle potential routing issues.

 tabPress: (e) => {
   e.preventDefault();
-  router.push({
-    pathname: "/(modal)/create-collaboration",
-  });
+  try {
+    router.push({
+      pathname: "/(modal)/create-collaboration",
+    });
+  } catch (error) {
+    console.error('Navigation failed:', error);
+    // Consider showing a user-friendly error message
+  }
 },

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

app/_layout.tsx (1)

146-148: 🛠️ Refactor suggestion

Consider adding consistent presentation options

The edit-collaboration screen should maintain consistency with create-collaboration screen's presentation options.

 <Stack.Screen
   name="(modal)/edit-collaboration"
+  options={{
+    presentation: "formSheet",
+    gestureEnabled: true,
+  }}
 />
📝 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.

          <Stack.Screen
            name="(modal)/edit-collaboration"
            options={{
              presentation: "formSheet",
              gestureEnabled: true,
            }}
          />
components/create-collaboration/screen-one.tsx (2)

185-197: ⚠️ Potential issue

Add budget range validation

The validation checks for empty fields but doesn't ensure that budgetMin <= budgetMax.

 if (
   !data.collaborationName ||
   !data.aboutCollab ||
   !data.budgetMin ||
   !data.budgetMax ||
   !data.numInfluencers ||
   !data.promotionType ||
   !data.collabType ||
   !data.platform
 ) {
   Toaster.error("Please fill all fields");
   return;
 }
+const minBudget = parseFloat(data.budgetMin);
+const maxBudget = parseFloat(data.budgetMax);
+if (isNaN(minBudget) || isNaN(maxBudget)) {
+  Toaster.error("Please enter valid budget values");
+  return;
+}
+if (minBudget > maxBudget) {
+  Toaster.error("Minimum budget cannot be greater than maximum budget");
+  return;
+}
 setScreen(2);
📝 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.

            if (
              !data.collaborationName ||
              !data.aboutCollab ||
              !data.budgetMin ||
              !data.budgetMax ||
              !data.numInfluencers ||
              !data.promotionType ||
              !data.collabType ||
              !data.platform
            ) {
              Toaster.error("Please fill all fields");
              return;
            }
            const minBudget = parseFloat(data.budgetMin);
            const maxBudget = parseFloat(data.budgetMax);
            if (isNaN(minBudget) || isNaN(maxBudget)) {
              Toaster.error("Please enter valid budget values");
              return;
            }
            if (minBudget > maxBudget) {
              Toaster.error("Minimum budget cannot be greater than maximum budget");
              return;
            }

91-107: 🛠️ Refactor suggestion

Consider adding numeric keyboard and input validation

The budget inputs should use numeric keyboard and validate input to ensure only valid numbers are entered.

 <TextInput
   label="Budget Min"
   mode="outlined"
   onChangeText={(text) => setState.budgetMin(text)}
   style={styles.budgetInput}
   textColor={Colors(theme).text}
   value={data.budgetMin}
+  keyboardType="numeric"
+  onChangeText={(text) => {
+    if (/^\d*\.?\d*$/.test(text)) {
+      setState.budgetMin(text);
+    }
+  }}
 />

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

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