Skip to content
Open
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"java.compile.nullAnalysis.mode": "automatic"
"java.compile.nullAnalysis.mode": "automatic",
"cSpell.words": [
"Verticborder"
]
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@neondatabase/serverless": "^1.0.0",
"@react-native-community/datetimepicker": "8.3.0",
"@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.1.17",
"@t3-oss/env-core": "^0.13.6",
"@tanstack/react-query": "^5.75.7",
"@trpc/client": "^11.1.2",
Expand Down
49 changes: 26 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
packages:
- 'src/*'
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

Treating every folder under src/ as a workspace package is risky for Expo/Metro.*

Metro + pnpm symlinks can misresolve modules unless you add custom metro.config and monorepo setup. Unless you truly have package boundaries in src/*, avoid making them workspace packages.

Recommended:

-packages:
-  - 'src/*'
+packages:
+  - 'apps/*'
+  - 'packages/*'
+# Keep app source under src/ inside the app package instead of top-level workspace packages.

If you must keep monorepo in src/*, ensure Metro is configured (watchFolders, resolver.disableHierarchicalLookup=false or equivalent) and NativeWind/babel paths handle symlinks.

📝 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
packages:
- 'src/*'
packages:
- 'apps/*'
- 'packages/*'
# Keep app source under src/ inside the app package instead of top-level workspace packages.
🤖 Prompt for AI Agents
In pnpm-workspace.yaml around lines 1-2, listing packages: - 'src/*' treats
every folder under src as a workspace package which breaks Expo/Metro; either
restrict the workspace globs to explicit package folders (e.g. move true
packages into a dedicated packages/ dir or list only the actual package paths
under src) or keep src/* but add the required Metro/React Native monorepo
config: add watchFolders pointing to workspace roots, set
resolver.disableHierarchicalLookup=false (or equivalent) and ensure
NativeWind/babel config handles symlinks; update pnpm-workspace.yaml to a narrow
set of package globs or move package folders and document the Metro config
changes.

onlyBuiltDependencies:
- '@clerk/shared'
- browser-tabs-lock
Expand Down
47 changes: 47 additions & 0 deletions src/app/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react"
import { ThemeProvider } from "~/contexts/ThemeContext"
import { ProfileScreen } from "~/components/profile/ProfileScreen"
import { LimitsScreen } from "~/components/profile/Limits"
import { IncomeScreen } from "~/components/profile/Income"
import { NotificationScreen } from "~/components/profile/Notification"
import { UserProfileScreen } from "~/components/profile/UserProfile"
import { BankAccountsScreen } from "~/components/profile/BankAccounts"

const ProfileAppContent: React.FC = () => {
const [currentScreen, setCurrentScreen] = React.useState("Profile")

const handleNavigate = (screen: string) => {
setCurrentScreen(screen)
}

const renderScreen = () => {
switch (currentScreen) {
case "Profile":
return <ProfileScreen onNavigate={handleNavigate} />
case "Limits":
return <LimitsScreen onNavigate={handleNavigate} />
case "Income":
return <IncomeScreen onNavigate={handleNavigate} />
case "Notification":
return <NotificationScreen onNavigate={handleNavigate} />
case "UserProfile":
return <UserProfileScreen onNavigate={handleNavigate} />
case "BankAccounts":
return <BankAccountsScreen onNavigate={handleNavigate} />
default:
return <ProfileScreen onNavigate={handleNavigate} />
}
}

return renderScreen()
}
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 21, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Do not implement a manual “router”; use Expo Router file-based routes.

Guideline: screens and routes live under src/app/. Replace local state switching with Expo Router (Stack/Tabs) and split each screen into its own route file: e.g., src/app/profile/index.tsx (menu), src/app/profile/limits.tsx, income.tsx, notification.tsx, user.tsx, bank-accounts.tsx. Pass data via params instead of custom onNavigate.

Minimal interim typing improvement if you keep this temporarily:

-  const [currentScreen, setCurrentScreen] = React.useState("Profile")
+  type Screen = "Profile" | "Limits" | "Income" | "Notification" | "UserProfile" | "BankAccounts"
+  const [currentScreen, setCurrentScreen] = React.useState<Screen>("Profile")
-  const handleNavigate = (screen: string) => {
+  const handleNavigate = (screen: Screen) => {
     setCurrentScreen(screen)
   }

Also consider removing @react-navigation/native if you won’t use it directly.

📝 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
const ProfileAppContent: React.FC = () => {
const [currentScreen, setCurrentScreen] = React.useState("Profile")
const handleNavigate = (screen: string) => {
setCurrentScreen(screen)
}
const renderScreen = () => {
switch (currentScreen) {
case "Profile":
return <ProfileScreen onNavigate={handleNavigate} />
case "Limits":
return <LimitsScreen onNavigate={handleNavigate} />
case "Income":
return <IncomeScreen onNavigate={handleNavigate} />
case "Notification":
return <NotificationScreen onNavigate={handleNavigate} />
case "UserProfile":
return <UserProfileScreen onNavigate={handleNavigate} />
case "BankAccounts":
return <BankAccountsScreen onNavigate={handleNavigate} />
default:
return <ProfileScreen onNavigate={handleNavigate} />
}
}
return renderScreen()
}
const ProfileAppContent: React.FC = () => {
type Screen = "Profile" | "Limits" | "Income" | "Notification" | "UserProfile" | "BankAccounts"
const [currentScreen, setCurrentScreen] = React.useState<Screen>("Profile")
const handleNavigate = (screen: Screen) => {
setCurrentScreen(screen)
}
const renderScreen = () => {
switch (currentScreen) {
case "Profile":
return <ProfileScreen onNavigate={handleNavigate} />
case "Limits":
return <LimitsScreen onNavigate={handleNavigate} />
case "Income":
return <IncomeScreen onNavigate={handleNavigate} />
case "Notification":
return <NotificationScreen onNavigate={handleNavigate} />
case "UserProfile":
return <UserProfileScreen onNavigate={handleNavigate} />
case "BankAccounts":
return <BankAccountsScreen onNavigate={handleNavigate} />
default:
return <ProfileScreen onNavigate={handleNavigate} />
}
}
return renderScreen()
}
🤖 Prompt for AI Agents
In src/app/profile/index.tsx around lines 10 to 37, the component implements a
manual router via local state and onNavigate props; replace this with Expo
Router file-based routes: create separate route files (src/app/profile/index.tsx
as the menu and src/app/profile/limits.tsx, income.tsx, notification.tsx,
user.tsx, bank-accounts.tsx) and navigate between them using Expo Router
navigation/Link or Stack/Tabs, passing any required data via route params
instead of onNavigate callbacks; remove the local currentScreen state and
onNavigate props from the child screens (or convert them to accept params), and
if you stop using react-navigation directly, remove @react-navigation/native
from dependencies; if you temporarily keep the manual switch for an interim
change, at minimum tighten typing by creating a ScreenName union type and typing
handleNavigate and currentScreen accordingly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@Psamcyite make a route file for the navigation routes its much cleaner that way to handle if we face any errors in the future and also a good standard to maintain

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!


const ProfileApp: React.FC = () => {
return (
<ThemeProvider>
<ProfileAppContent />
</ThemeProvider>
)
}

export default ProfileApp
Binary file added src/assets/Icons/Y.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/bank_account.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/banking.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/entertainment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/income.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/insights.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/key-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/limits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/netflix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/notification.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/plus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/rent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Icons/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 26 additions & 9 deletions src/components/AccountItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ export const AccountItem: React.FC<AccountItemProps> = ({

const Component = onPress ? TouchableOpacity : View

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

Union element misuse: passing activeOpacity to View triggers type/runtime issues.

const Component = onPress ? TouchableOpacity : View and always passing activeOpacity causes TS prop mismatch and RN warnings. Render conditionally or switch to Pressable.

Apply:

-  const Component = onPress ? TouchableOpacity : View
+  // Use explicit branches to avoid invalid props on View

And in render:

-      <Component
-        onPress={onPress}
-        activeOpacity={onPress ? 0.7 : 1}
-        className="flex-row items-center py-4 px-5 rounded-xl border"
-        style={{
-          backgroundColor: colors.cardBackground,
-          borderColor: colors.border,
-        }}
-      >
+      {onPress ? (
+        <TouchableOpacity
+          onPress={onPress}
+          activeOpacity={0.7}
+          className="flex-row items-center rounded-xl border px-5 py-4"
+          style={{ backgroundColor: colors.cardBackground, borderColor: colors.border }}
+        >
+          <View className="mr-4 h-10 w-10">{icon}</View>
+          <AppText medium className="flex-1 text-base" style={{ color: colors.text }}>
+            {name}
+          </AppText>
+          <IconWrapper height={40} width={60}>
+            <AppText semibold className="text-base" style={{ color: colors.text }}>
+              {amount}
+            </AppText>
+          </IconWrapper>
+        </TouchableOpacity>
+      ) : (
+        <View
+          className="flex-row items-center rounded-xl border px-5 py-4"
+          style={{ backgroundColor: colors.cardBackground, borderColor: colors.border }}
+        >
+          <View className="mr-4 h-10 w-10">{icon}</View>
+          <AppText medium className="flex-1 text-base" style={{ color: colors.text }}>
+            {name}
+          </AppText>
+          <IconWrapper height={40} width={60}>
+            <AppText semibold className="text-base" style={{ color: colors.text }}>
+              {amount}
+            </AppText>
+          </IconWrapper>
+        </View>
+      )}
📝 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
const Component = onPress ? TouchableOpacity : View
// Use explicit branches to avoid invalid props on View
{onPress ? (
<TouchableOpacity
onPress={onPress}
activeOpacity={0.7}
className="flex-row items-center rounded-xl border px-5 py-4"
style={{ backgroundColor: colors.cardBackground, borderColor: colors.border }}
>
<View className="mr-4 h-10 w-10">{icon}</View>
<AppText medium className="flex-1 text-base" style={{ color: colors.text }}>
{name}
</AppText>
<IconWrapper height={40} width={60}>
<AppText semibold className="text-base" style={{ color: colors.text }}>
{amount}
</AppText>
</IconWrapper>
</TouchableOpacity>
) : (
<View
className="flex-row items-center rounded-xl border px-5 py-4"
style={{ backgroundColor: colors.cardBackground, borderColor: colors.border }}
>
<View className="mr-4 h-10 w-10">{icon}</View>
<AppText medium className="flex-1 text-base" style={{ color: colors.text }}>
{name}
</AppText>
<IconWrapper height={40} width={60}>
<AppText semibold className="text-base" style={{ color: colors.text }}>
{amount}
</AppText>
</IconWrapper>
</View>
)}
🤖 Prompt for AI Agents
In src/components/AccountItem.tsx around lines 24-25, you currently assign
Component = onPress ? TouchableOpacity : View and then always pass activeOpacity
which causes a prop/type mismatch; fix by either (A) rendering TouchableOpacity
conditionally only when onPress is present (i.e. return <TouchableOpacity ...>
when onPress else <View ...>), ensuring activeOpacity is only passed to
TouchableOpacity, or (B) switch to React Native Pressable for both cases and use
its supported props (remove activeOpacity and use press retention/opacity
styles), and update imports/types accordingly so TypeScript no longer complains.

const IconWrapper = ({
children,
H_size = 40,
W_size = 60,
}: {
children: React.ReactNode
H_size?: number
W_size?: number
}) => (
<View
className="rounded-2xl items-center justify-center"
style={{
width: W_size,
height: H_size,
backgroundColor: colors.border,
}}
>
{children}
</View>
)

return (
<Animated.View
entering={FadeInDown.delay(delay).springify()}
Expand All @@ -38,22 +59,18 @@ export const AccountItem: React.FC<AccountItemProps> = ({
}}
>
<View className="w-10 h-10 mr-4">{icon}</View>

<AppText
medium
className="flex-1 text-base"
style={{ color: colors.text }}
>
{name}
</AppText>

<AppText
semibold
className="text-base"
style={{ color: colors.accent }}
>
{amount}
</AppText>
<IconWrapper H_size={40} W_size={60}>
<AppText semibold className="text-base" style={{ color: colors.text }}>
{amount}
</AppText>
</IconWrapper>
</Component>
</Animated.View>
)
Expand Down
45 changes: 26 additions & 19 deletions src/components/AppText.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from "react";
import { Text, StyleSheet } from "react-native";
import { useFonts } from "expo-font";
import React from "react"
import { Text } from "react-native"
import { useFonts } from "expo-font"

type AppTextProps = {
semibold?: boolean;
children: React.ReactNode;
medium?: boolean;
bold?: boolean;
className?: string;
style?: object;
};
semibold?: boolean
children: React.ReactNode
medium?: boolean
bold?: boolean
className?: string
style?: object
}

export default function AppText({
children,
Expand All @@ -20,29 +20,36 @@ export default function AppText({
style,
...rest
}: AppTextProps & Omit<React.ComponentProps<typeof Text>, keyof AppTextProps>) {
// This is a Component that we use to render text with custom fonts

const [fontsLoaded] = useFonts({
Raleway: require("~/assets/fonts/Raleway-Regular.ttf"),
RalewayMedium: require("~/assets/fonts/Raleway-Medium.ttf"),
RalewaySemiBold: require("~/assets/fonts/Raleway-SemiBold.ttf"),
RalewayBold: require("~/assets/fonts/Raleway-Bold.ttf"),
});
})

if (!fontsLoaded) {
return null;
return null
}

const fontFamily = semibold
? "RalewaySemiBold"
: medium
? "RalewayMedium"
: bold
? "RalewayBold"
: "Raleway";
? "RalewayMedium"
: bold
? "RalewayBold"
: "Raleway"

return (
<Text className={className} style={{ fontFamily, ...style }} {...rest}>
<Text
className={className}
style={[
{ fontFamily},
style,
]}
{...rest}
>
{children}
</Text>
);
)
}
Loading