Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions app/(auth)/create-new-account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useRouter } from "expo-router";
import { useState } from "react";
import {
View,
StyleSheet,
Image,
Text,
ScrollView,
Expand All @@ -14,7 +13,6 @@ import { TextInput, Button } from "react-native-paper";
import fnStyles from "@/styles/signup.styles";
import { useTheme } from "@react-navigation/native";
import { useAuthContext } from "@/contexts";
import Toast from "react-native-toast-message";
import Colors from "@/constants/Colors";

const SignUpScreen = () => {
Expand Down Expand Up @@ -43,7 +41,6 @@ const SignUpScreen = () => {
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
>
<Toast />
{/* Logo Section */}
<Image
source={require("@/assets/images/logo.png")}
Expand Down Expand Up @@ -95,10 +92,8 @@ const SignUpScreen = () => {
<Button
mode="contained"
onPress={() => signUp(name, email, password)}
style={styles.button}
labelStyle={styles.buttonText}
>
SIGN UP
Signup

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent text casing found across auth screens

The casing is indeed inconsistent across the auth screens:

  • "Signup" in create-new-account.tsx and signup.tsx
  • "Login" in login.tsx
  • "Sign Up" (with a space) in login.tsx navigation link

Locations that need attention:

  • app/(auth)/create-new-account.tsx: "Signup"
  • app/(auth)/signup.tsx: "Signup"
  • app/(auth)/login.tsx: "Login" and "Sign Up"
🔗 Analysis chain

Verify text casing consistency across auth screens

The button text has been changed to "Signup". While this change is acceptable, we should ensure consistent casing across all auth-related buttons (login, signup, etc.) in the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check button text consistency across auth screens
# Look for Button components with text variations of login/signup
rg -A 1 'Button.*mode="contained"' "app/(auth)/"

Length of output: 50


Script:

#!/bin/bash
# Let's try a broader search for Button components in auth screens
rg -i "button.*>.*(?:sign|log)" "app/(auth)/"

# Also search for Text components that might contain auth-related text
rg -i "text.*>.*(?:sign|log)" "app/(auth)/"

# And a general search for these terms to catch other implementations
rg -i "(?:signup|sign up|login|log in)" "app/(auth)/"

Length of output: 2380

</Button>
Comment on lines 92 to 97

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add loading state and error handling to improve UX

The signup button lacks loading state and error handling, which could lead to a poor user experience if the signup process takes time or fails.

Consider implementing these improvements:

+const [isLoading, setIsLoading] = useState(false);
+const [error, setError] = useState<string | null>(null);

+const handleSignUp = async () => {
+  try {
+    setError(null);
+    setIsLoading(true);
+    await signUp(name, email, password);
+  } catch (err) {
+    setError(err.message);
+  } finally {
+    setIsLoading(false);
+  }
+};

 <Button
   mode="contained"
-  onPress={() => signUp(name, email, password)}
+  onPress={handleSignUp}
+  loading={isLoading}
+  disabled={isLoading}
 >
   Signup
 </Button>
+{error && <Text style={styles.errorText}>{error}</Text>}

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


🛠️ Refactor suggestion

Add client-side validation before submission

The signup function is called without validating the user input, which could lead to unnecessary server calls and poor user feedback.

Consider adding basic validation:

+const validateForm = () => {
+  if (!name.trim()) return "Name is required";
+  if (!email.trim()) return "Email is required";
+  if (!/\S+@\S+\.\S+/.test(email)) return "Invalid email format";
+  if (!password) return "Password is required";
+  if (password.length < 8) return "Password must be at least 8 characters";
+  if (password !== confirmPassword) return "Passwords do not match";
+  return null;
+};

+const handleSignUp = async () => {
+  const error = validateForm();
+  if (error) {
+    setError(error);
+    return;
+  }
+  try {
+    setError(null);
+    setIsLoading(true);
+    await signUp(name, email, password);
+  } catch (err) {
+    setError(err.message);
+  } finally {
+    setIsLoading(false);
+  }
+};

 <Button
   mode="contained"
-  onPress={() => signUp(name, email, password)}
+  onPress={handleSignUp}
 >

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

</View>
{/* Login Prompt */}
Expand Down
4 changes: 0 additions & 4 deletions app/(auth)/forget-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { TextInput, Button } from "react-native-paper";
import { sendPasswordResetEmail } from "firebase/auth";
import { AuthApp } from "@/utils/auth";
import Toaster from "@/shared-uis/components/toaster/Toaster";
import Toast from "react-native-toast-message";
import Colors from "@/constants/Colors";

const ForgotPasswordScreen = () => {
Expand Down Expand Up @@ -37,7 +36,6 @@ const ForgotPasswordScreen = () => {
return (
<View style={styles.container}>
{/* Logo Section */}
<Toast />
<Image
source={require("@/assets/images/logo.png")} // Replace with your actual logo path
style={styles.logo}
Expand All @@ -63,8 +61,6 @@ const ForgotPasswordScreen = () => {
onPress={() => {
handleResetPassword();
}}
style={styles.button}
labelStyle={styles.buttonText}
>
Reset Password
</Button>
Expand Down
4 changes: 0 additions & 4 deletions app/(auth)/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { TextInput, Button } from "react-native-paper";
import { useRouter } from "expo-router";
import { useTheme } from "@react-navigation/native";
import fnStyles from "@/styles/login.styles";
import Toast from "react-native-toast-message";
import Colors from "@/constants/Colors";

const LoginScreen = () => {
Expand All @@ -23,7 +22,6 @@ const LoginScreen = () => {

return (
<View style={styles.container}>
<Toast />
{/* Logo Section */}
<Image
source={require("@/assets/images/logo.png")} // Replace with your actual logo path
Expand Down Expand Up @@ -60,8 +58,6 @@ const LoginScreen = () => {
<Button
mode="contained"
onPress={() => handleSignIn()}
style={styles.button}
labelStyle={styles.buttonText}
>
Login
</Button>
Expand Down
60 changes: 43 additions & 17 deletions app/(main)/(drawer)/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import FontAwesome from "@expo/vector-icons/FontAwesome";
import { router, Tabs } from "expo-router";

import Colors from "@/constants/Colors";
Expand All @@ -10,15 +9,18 @@ import NotificationIcon from "@/components/notifications/notification-icon";
import MenuIcon from "@/components/ui/menu-icon";
import { View } from "@/components/theme/Themed";
import DrawerToggleButton from "@/components/ui/drawer-toggle-button/DrawerToggleButton";
import { Octicons } from "@expo/vector-icons";
import BrandSwitcher from "@/components/ui/brand-switcher";

const TabBarIcon = (props: {
name: React.ComponentProps<typeof FontAwesome>["name"];
color: string;
}) => {
return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
};
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome";
import {
faHandshake,
faComment,
faStar,
} from "@fortawesome/free-regular-svg-icons";
import {
faFileSignature,
faPlusCircle,
faRightLeft,
} from "@fortawesome/free-solid-svg-icons";

const TabLayout = () => {
const { xl } = useBreakpoints();
Expand All @@ -33,6 +35,7 @@ const TabLayout = () => {
tabBarHideOnKeyboard: true,
tabBarStyle: {
display: xl ? "none" : "flex", // Hide the tab bar on desktop screens
paddingHorizontal: 8,
},
headerTitleAlign: "left",
headerTitleStyle: {
Expand All @@ -46,17 +49,22 @@ const TabLayout = () => {
options={{
title: "Explore Influencers",
tabBarIcon: ({ color }) => (
<TabBarIcon name="handshake-o" color={color} />
<FontAwesomeIcon
color={color}
icon={faHandshake}
size={28}
/>
),
headerLeft: () =>
xl ? (
<BrandSwitcher />
) : (
<DrawerToggleButton
icon={
<Octicons
name="arrow-switch"
size={26}
<FontAwesomeIcon
color={Colors(theme).text}
icon={faRightLeft}
size={24}
style={{
marginLeft: 14,
color: Colors(theme).text,
Expand Down Expand Up @@ -84,7 +92,13 @@ const TabLayout = () => {
name="collaborations"
options={{
title: "Collaborations",
tabBarIcon: ({ color }) => <TabBarIcon name="group" color={color} />,
tabBarIcon: ({ color }) => (
<FontAwesomeIcon
color={color}
icon={faStar}
size={24}
/>
),
headerRight: () => <NotificationIcon />,
}}
/>
Expand All @@ -100,15 +114,23 @@ const TabLayout = () => {
headerShown: false,
title: "Create Collaborations",
tabBarIcon: ({ color }) => (
<TabBarIcon name="plus-circle" color={color} />
<FontAwesomeIcon
color={color}
icon={faPlusCircle}
size={24}
/>
),
}}
/>
<Tabs.Screen
name="messages"
options={{
tabBarIcon: ({ color }) => (
<TabBarIcon name="comments" color={color} />
<FontAwesomeIcon
color={color}
icon={faComment}
size={24}
/>
),
title: "Messages",
headerTitleAlign: "left",
Expand All @@ -120,7 +142,11 @@ const TabLayout = () => {
options={{
title: "Contracts",
tabBarIcon: ({ color }) => (
<TabBarIcon name="file-text-o" color={color} />
<FontAwesomeIcon
color={color}
icon={faFileSignature}
size={24}
/>
),
headerRight: () => <NotificationIcon />,
}}
Expand Down
33 changes: 5 additions & 28 deletions app/(main)/(screens)/CollaborationHistory.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
import BackButton from "@/components/ui/back-button/BackButton";
import React from "react";
import AppLayout from "@/layouts/app-layout";
import { stylesFn } from "@/styles/CollaborationHistory.styles";
import { useTheme } from "@react-navigation/native";
import React, { useState } from "react";
import { View, ScrollView, StyleSheet } from "react-native";
import {
TextInput,
Button,
Title,
Paragraph,
IconButton,
RadioButton,
} from "react-native-paper";
import ScreenHeader from "@/components/ui/screen-header";

Comment on lines +1 to 4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Component name doesn't match the file name

The file is named CollaborationHistory.tsx but exports a component named CreateCollaborationScreen. This naming inconsistency could lead to confusion. Consider renaming either:

  • The component to CollaborationHistory to match the file name, or
  • The file to CreateCollaborationScreen.tsx to match the component name

const CreateCollaborationScreen = () => {
const theme = useTheme();
const styles = stylesFn(theme);
return (
<AppLayout>
<ScrollView style={styles.container}>
<View
style={{
flexDirection: "row",
alignItems: "center",
marginBottom: 16,
gap: 16,
}}
>
<BackButton />
<Title style={styles.title}>Collaboration History</Title>
</View>
</ScrollView>
<ScreenHeader
title="Collaboration History"
/>
</AppLayout>
);
};
Comment on lines 6 to 13

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codebase verification

Component name inconsistent with its purpose

The component is named CreateCollaborationScreen but it's clearly a history view component based on:

  1. The rendered title "Collaboration History"
  2. The file name CollaborationHistory.tsx
  3. The existence of separate creation-related files (CreateCollaborationMap.tsx and CreateCollaborationForm.ts)

The component should be renamed to match its purpose:

  • Change the component name from CreateCollaborationScreen to CollaborationHistoryScreen
  • Update any imports/references accordingly
🔗 Analysis chain

Verify component purpose and functionality

The component name CreateCollaborationScreen suggests creation functionality, but it appears to be a history view based on the title "Collaboration History". This seems contradictory. Please verify:

  1. Is this meant to be a creation screen or a history view?
  2. If it's a creation screen, where is the creation functionality?
  3. If it's a history view, shouldn't the component be renamed?

Let's check for related components and usage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for related collaboration components and their usage
echo "Searching for collaboration-related components..."
rg -l "Collaboration" --type tsx

echo "\nChecking for references to this component..."
rg "CreateCollaborationScreen" --type tsx

Length of output: 342


Script:

#!/bin/bash
# Search for related collaboration components and their usage with correct file extensions
echo "Searching for collaboration-related files..."
fd -e tsx -e ts "Collaboration"

echo "\nSearching for collaboration-related content..."
rg "Collaboration" -t ts -t tsx

echo "\nChecking component references..."
rg "CreateCollaborationScreen" -t ts -t tsx

Length of output: 919


Script:

#!/bin/bash
# Let's check the content of the file to understand its actual purpose
echo "Checking the full content of CollaborationHistory.tsx..."
cat "app/(main)/(screens)/CollaborationHistory.tsx"

echo "\nChecking create collaboration related files..."
cat "components/collaboration/create-collaboration/CreateCollaborationMap.tsx"
cat "constants/CreateCollaborationForm.ts"

Length of output: 3392

Expand Down
5 changes: 0 additions & 5 deletions app/(main)/(screens)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ const ScreensLayout = () => {
>
<Stack.Screen name="notifications" />
<Stack.Screen name="menu" />
<Stack.Screen name="brand-profile" />
<Stack.Screen name="profile" />
<Stack.Screen name="CollaborationHistory" />
<Stack.Screen name="preferences" />
<Stack.Screen name="settings" />
<Stack.Screen name="billing" />
</Stack>
</AppLayout>
);
Expand Down
86 changes: 21 additions & 65 deletions app/(main)/(screens)/collaboration-details/[pageID].tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,33 @@
import CollaborationPage from "@/components/collaboration/CollaborationDetails";
import { useEffect, useState } from "react";
import { doc, getDoc } from "firebase/firestore";
import { useLocalSearchParams } from "expo-router";
import { FirestoreDB } from "@/utils/firestore";
import BottomSheetActions from "@/components/BottomSheetActions";
import CollaborationDetails from "@/components/collaboration/collaboration-details";
import ScreenHeader from "@/components/ui/screen-header";
import AppLayout from "@/layouts/app-layout";
import { ActivityIndicator, Chip } from "react-native-paper";
import { ICollaboration } from "@/shared-libs/firestore/trendly-pro/models/collaborations";
import { View } from "@/components/theme/Themed";
import { ScrollView, StyleSheet } from "react-native";

interface Collaboration extends ICollaboration {
brandName: string;
paymentVerified: boolean;
brandDescription: string;
}
import { useLocalSearchParams } from "expo-router";
import { useState } from "react";

const CollaborationDetailsScreen = () => {
const [isVisible, setIsVisible] = useState(false);
const pageID = useLocalSearchParams().pageID;
const [collaboration, setCollaboration] = useState<Collaboration | undefined>(
undefined
); // Explicit type
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState("Overview");
const fetchCollaboration = async () => {
if (!pageID) return;
try {
const collabRef = doc(FirestoreDB, "collaborations", pageID as string);
const snapshot = await getDoc(collabRef);
const data = snapshot.data() as ICollaboration;
if (!data) return;

const brandRef = doc(FirestoreDB, "brands", data.brandId);
const brandSnapshot = await getDoc(brandRef);
const brandData = brandSnapshot.data();

setCollaboration({
...data,
brandName: brandData?.name || "Unknown Brand",
paymentVerified: brandData?.paymentMethodVerified || false,
brandDescription: brandData?.description || "",
});
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
};

useEffect(() => {
fetchCollaboration();
}, [pageID]);

if (loading)
return (
<AppLayout>
<ActivityIndicator />
</AppLayout>
);

if (!collaboration) return null;

return (
<AppLayout>
{activeTab === "Overview" && (
<CollaborationPage
collaborationDetail={collaboration}
pageID={pageID}
/>
)}
<ScreenHeader
title="Collaboration Details"
/>
<CollaborationDetails
pageID={pageID as string}
/>
Comment on lines +17 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the previous results and this search, I can now generate the final response:

Error handling needs improvement in CollaborationDetails

While the component implements loading states and basic try-catch blocks, it lacks proper error UI feedback:

  • Loading states are properly handled with loading spinners
  • Error cases only log to console without showing user-facing error messages
  • No error boundary implementation found for catching rendering errors
🔗 Analysis chain

Verify error handling in CollaborationDetails

Since the loading and error states have been moved to the CollaborationDetails component, let's verify its implementation.


Let me generate additional scripts to verify the error UI states and error boundaries:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check CollaborationDetails implementation for error handling
ast-grep --pattern 'function CollaborationDetails($_) {
  $$$
}'

# Look for error handling patterns
rg -A 5 'try.*catch|error|loading' components/collaboration/collaboration-details

Length of output: 4795


Script:

#!/bin/bash
# Check for error UI states and error boundaries
rg -A 3 'error.*state|error.*message|ErrorBoundary' components/collaboration/collaboration-details

# Check if there's any error UI component being rendered
ast-grep --pattern 'return (
  <$_>
    $$$
    {error && $_}
    $$$
  </$_>
)'

Length of output: 183

<BottomSheetActions
cardId={pageID as string}
cardType="influencerCard"
isVisible={isVisible}
snapPointsRange={["20%", "50%"]}
onClose={() => {
setIsVisible(false);
}}
/>
</AppLayout>
);
};

export default CollaborationDetailsScreen;

const styles = StyleSheet.create({});
1 change: 0 additions & 1 deletion app/(main)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ChatContextProvider } from "@/contexts";
import { BrandContextProvider } from "@/contexts/brand-context.provider";
import { Stack } from "expo-router";

const MainLayout = () => {
Expand Down
Loading