diff --git a/apps/mobile/app/(app)/(tabs)/settings.tsx b/apps/mobile/app/(app)/(tabs)/settings.tsx
index 65547877..81a26bbb 100644
--- a/apps/mobile/app/(app)/(tabs)/settings.tsx
+++ b/apps/mobile/app/(app)/(tabs)/settings.tsx
@@ -94,17 +94,19 @@ export default function SettingsScreen() {
className="bg-card"
>
-
+
+
+
{t(i18n)`General`}
diff --git a/apps/mobile/app/(app)/_layout.tsx b/apps/mobile/app/(app)/_layout.tsx
index fd633ba3..c63e1d65 100644
--- a/apps/mobile/app/(app)/_layout.tsx
+++ b/apps/mobile/app/(app)/_layout.tsx
@@ -106,6 +106,13 @@ export default function AuthenticatedLayout() {
headerTitle: t(i18n)`Feedback`,
}}
/>
+
+
+
+
+ {title}
+
+
+
+ )
+}
+
+export default function PaywallScreen() {
+ const { i18n } = useLingui()
+ const [plan, setPlan] = useState<'growth' | 'wealth'>('growth')
+
+ const proFeatures = [
+ {
+ source: require('../../assets/images/paywall-images/2.png'),
+ title: t(i18n)`Unlimited`,
+ },
+ {
+ source: require('../../assets/images/paywall-images/3.png'),
+ title: t(i18n)`AI Insights`,
+ },
+ {
+ source: require('../../assets/images/paywall-images/4.png'),
+ title: t(i18n)`Multi-currencies`,
+ },
+ {
+ source: require('../../assets/images/paywall-images/1.png'),
+ title: t(i18n)`Security`,
+ },
+ ]
+
+ const plans = {
+ growth: [
+ t(i18n)`Up to 10 AI transactions per day`,
+ t(i18n)`Unlimited transactions & categories`,
+ t(i18n)`6 budgets & 6 accounts`,
+ t(i18n)`Multi-currencies & customizations`,
+ ],
+ wealth: [
+ t(i18n)`Up to 25 AI transactions per day`,
+ t(i18n)`All features of growth plan`,
+ t(i18n)`Unlimited budgets & accounts`,
+ t(i18n)`Most advanced financial AI assistant`,
+ ],
+ }
+
+ return (
+
+
+ {t(i18n)`Complete control over your finances`}
+
+
+ {
+ setPlan(value as 'growth' | 'wealth')
+ }}
+ >
+
+
+ {t(i18n)`Growth`}
+
+
+ {t(i18n)`Wealth`}
+
+
+
+
+ {plans[plan].map((item) => (
+
+
+ {item}
+
+ ))}
+
+
+
+
+ 1
+
+ month
+
+
+
+
+
+
+
+ {t(i18n)`Best value`}
+
+
+
+ 12
+
+ months
+
+
+
+
+
+
+
+
+ Privacy Policy
+
+
+
+
+ )
+}
diff --git a/apps/mobile/assets/images/paywall-images/1.png b/apps/mobile/assets/images/paywall-images/1.png
new file mode 100644
index 00000000..e39fc985
Binary files /dev/null and b/apps/mobile/assets/images/paywall-images/1.png differ
diff --git a/apps/mobile/assets/images/paywall-images/2.png b/apps/mobile/assets/images/paywall-images/2.png
new file mode 100644
index 00000000..c6d90633
Binary files /dev/null and b/apps/mobile/assets/images/paywall-images/2.png differ
diff --git a/apps/mobile/assets/images/paywall-images/3.png b/apps/mobile/assets/images/paywall-images/3.png
new file mode 100644
index 00000000..5ac6e11c
Binary files /dev/null and b/apps/mobile/assets/images/paywall-images/3.png differ
diff --git a/apps/mobile/assets/images/paywall-images/4.png b/apps/mobile/assets/images/paywall-images/4.png
new file mode 100644
index 00000000..1f1f79c0
Binary files /dev/null and b/apps/mobile/assets/images/paywall-images/4.png differ
diff --git a/apps/mobile/components/common/marquee.tsx b/apps/mobile/components/common/marquee.tsx
new file mode 100644
index 00000000..96a44aa8
--- /dev/null
+++ b/apps/mobile/components/common/marquee.tsx
@@ -0,0 +1,129 @@
+import * as React from 'react'
+import type { ViewStyle } from 'react-native'
+import { StyleSheet } from 'react-native'
+import { View } from 'react-native'
+import type { SharedValue } from 'react-native-reanimated'
+import Animated, {
+ runOnJS,
+ useAnimatedReaction,
+ useAnimatedStyle,
+ useFrameCallback,
+ useSharedValue,
+} from 'react-native-reanimated'
+
+const AnimatedChild = ({
+ index,
+ children,
+ anim,
+ textWidth,
+ spacing,
+}: React.PropsWithChildren<{
+ index: number
+ anim: SharedValue
+ textWidth: SharedValue
+ spacing: number
+}>) => {
+ const stylez = useAnimatedStyle(() => {
+ return {
+ position: 'absolute',
+ left: index * (textWidth.value + spacing),
+ transform: [
+ {
+ translateX: -(anim.value % (textWidth.value + spacing)),
+ },
+ ],
+ }
+ }, [index, spacing, textWidth])
+ return {children}
+}
+
+export type MarqueeProps = React.PropsWithChildren<{
+ speed?: number
+ spacing?: number
+ style?: ViewStyle
+}>
+
+/**
+ * Used to animate the given children in a horizontal manner.
+ */
+export const Marquee = React.memo(
+ ({ speed = 1, children, spacing = 0, style }: MarqueeProps) => {
+ const parentWidth = useSharedValue(0)
+ const textWidth = useSharedValue(0)
+ const [cloneTimes, setCloneTimes] = React.useState(0)
+ const anim = useSharedValue(0)
+
+ useFrameCallback(() => {
+ anim.value += speed
+ }, true)
+
+ useAnimatedReaction(
+ () => {
+ if (textWidth.value === 0 || parentWidth.value === 0) {
+ return 0
+ }
+ return Math.round(parentWidth.value / textWidth.value) + 1
+ },
+ (v) => {
+ if (v === 0) {
+ return
+ }
+ // This is going to cover the case when the text/element size
+ // is greater than the actual parent size
+ // Double this to cover the entire screen twice, in this way we can
+ // reset the position of the first element when its going to move out
+ // of the screen without any noticible glitch
+ runOnJS(setCloneTimes)(v * 2)
+ },
+ [],
+ )
+ return (
+ {
+ parentWidth.value = ev.nativeEvent.layout.width
+ }}
+ pointerEvents="box-none"
+ >
+
+ {
+ // We are adding the text inside a ScrollView because in this way we
+ // ensure that its not going to "wrap".
+ }
+
+ {
+ textWidth.value = ev.nativeEvent.layout.width
+ }}
+ >
+ {children}
+
+
+ {cloneTimes > 0 &&
+ [...Array(cloneTimes).keys()].map((index) => {
+ return (
+
+ {children}
+
+ )
+ })}
+
+
+ )
+ },
+)
+
+const styles = StyleSheet.create({
+ hidden: { opacity: 0, zIndex: -9999 },
+ row: { flexDirection: 'row', overflow: 'hidden' },
+})
diff --git a/apps/mobile/components/svg-assets/paywall-illustration.tsx b/apps/mobile/components/svg-assets/paywall-illustration.tsx
new file mode 100644
index 00000000..3ceadebc
--- /dev/null
+++ b/apps/mobile/components/svg-assets/paywall-illustration.tsx
@@ -0,0 +1,49 @@
+import Svg, { type SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg'
+export const PaywallIllustration = (props: SvgProps) => (
+
+)
diff --git a/apps/mobile/components/ui/tabs.tsx b/apps/mobile/components/ui/tabs.tsx
index 057e5df2..e69a4f37 100644
--- a/apps/mobile/components/ui/tabs.tsx
+++ b/apps/mobile/components/ui/tabs.tsx
@@ -12,7 +12,7 @@ const TabsList = React.forwardRef<