Skip to content
Open
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
16 changes: 13 additions & 3 deletions app/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as Linking from "expo-linking";
import { Stack, useRouter } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { useEffect } from "react";
import { useColorScheme } from "react-native";
import { ThemeProvider as AppThemeProvider, useAppTheme } from "@/context/ThemeContext";
// Ensure web build or Expo web uses the local backend during development
if (typeof document !== "undefined" && !(global as any).API_BASE_URL) {
// Expo web typically runs on localhost; ensure the app hits the backend on port 4000
Expand Down Expand Up @@ -64,7 +64,15 @@ function DevPoller() {
}

export default function RootLayout() {
const colorScheme = useColorScheme();
return (
<AppThemeProvider>
<ThemedNavigationProvider />
</AppThemeProvider>
);
}

function ThemedNavigationProvider() {
const { colorScheme } = useAppTheme();

return (
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
Expand All @@ -81,7 +89,7 @@ export default function RootLayout() {
<ToastNotification />
</NotificationProvider>
</SecurityProvider>
<StatusBar style="auto" />
<StatusBar style={colorScheme === "dark" ? "light" : "dark"} />
</ThemeProvider>
);
}
Expand All @@ -100,6 +108,8 @@ function AppShell() {
<Stack.Screen name="scan-to-pay" />
<Stack.Screen name="payment-confirmation" />
<Stack.Screen name="transactions" />
<Stack.Screen name="settings" />
<Stack.Screen name="quick-receive" />
</Stack>
{isReady && settings.biometricLockEnabled ? (
<AppLockOverlay visible={isAppLocked} onUnlock={unlockApp} />
Expand Down
214 changes: 110 additions & 104 deletions app/mobile/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,151 +3,157 @@ import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import NotificationCenter from "../components/notifications/NotificationCenter";
import { useAppTheme } from "@/context/ThemeContext";

export default function HomeScreen() {
const { colors } = useAppTheme();
const s = makeStyles(colors);

return (
<SafeAreaView style={styles.container}>
<SafeAreaView style={s.container}>
<View style={{ position: "absolute", top: 12, right: 16, zIndex: 100 }}>
{/* Bell */}
<NotificationCenter />
</View>
<View style={styles.content}>
<Text style={styles.title}>QuickEx</Text>
<View style={s.content}>
<Text style={s.title}>QuickEx</Text>

<Text style={styles.subtitle}>
<Text style={s.subtitle}>
Fast, privacy-focused payment link platform built on Stellar.
</Text>

<View style={styles.card}>
<Text style={styles.cardTitle}>Instant Payments</Text>
<Text style={styles.cardText}>
<View style={s.card}>
<Text style={s.cardTitle}>Instant Payments</Text>
<Text style={s.cardText}>
Receive USDC, XLM, or any Stellar asset directly to your
self-custody wallet.
</Text>
</View>

<Link href="/scan-to-pay" asChild>
<TouchableOpacity style={styles.primaryButton}>
<Text style={styles.primaryButtonText}>Scan to Pay</Text>
<TouchableOpacity style={s.primaryButton}>
<Text style={s.primaryButtonText}>Scan to Pay</Text>
</TouchableOpacity>
</Link>

<Link href="/wallet-connect" asChild>
<TouchableOpacity style={styles.primaryButton}>
<Text style={styles.primaryButtonText}>Connect Wallet</Text>
<TouchableOpacity style={s.primaryButton}>
<Text style={s.primaryButtonText}>Connect Wallet</Text>
</TouchableOpacity>
</Link>

<Link href="/security" asChild>
<TouchableOpacity style={styles.secondaryButton}>
<Text style={styles.secondaryButtonText}>Security Settings</Text>
<TouchableOpacity style={s.secondaryButton}>
<Text style={s.secondaryButtonText}>Security Settings</Text>
</TouchableOpacity>
</Link>

{/* Quick Receive */}
<Link href="/quick-receive" asChild>
<TouchableOpacity style={styles.quickReceiveButton}>
<Text style={styles.quickReceiveButtonText}>Quick Receive</Text>
<TouchableOpacity style={s.quickReceiveButton}>
<Text style={s.quickReceiveButtonText}>Quick Receive</Text>
</TouchableOpacity>
</Link>

{/* Transaction History */}
<Link href="/transactions" asChild>
<TouchableOpacity style={styles.secondaryButton}>
<Text style={styles.secondaryButtonText}>Transaction History</Text>
<TouchableOpacity style={s.secondaryButton}>
<Text style={s.secondaryButtonText}>Transaction History</Text>
</TouchableOpacity>
</Link>
</View>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ffffff",
},
content: {
flex: 1,
padding: 24,
justifyContent: "center",
alignItems: "center",
},
title: {
fontSize: 42,
fontWeight: "bold",
color: "#000",
marginBottom: 8,
},
subtitle: {
fontSize: 18,
color: "#666",
textAlign: "center",
marginBottom: 40,
},
card: {
width: "100%",
padding: 20,
borderRadius: 12,
backgroundColor: "#f5f5f5",
marginBottom: 30,
},
cardTitle: {
fontSize: 20,
fontWeight: "600",
color: "#333",
marginBottom: 8,
},
cardText: {
fontSize: 16,
color: "#555",
lineHeight: 22,
},
function makeStyles(colors: ReturnType<typeof useAppTheme>["colors"]) {
return StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background,
},
content: {
flex: 1,
padding: 24,
justifyContent: "center",
alignItems: "center",
},
title: {
fontSize: 42,
fontWeight: "bold",
color: colors.text,
marginBottom: 8,
},
subtitle: {
fontSize: 18,
color: colors.textSecondary,
textAlign: "center",
marginBottom: 40,
},
card: {
width: "100%",
padding: 20,
borderRadius: 12,
backgroundColor: colors.card,
marginBottom: 30,
},
cardTitle: {
fontSize: 20,
fontWeight: "600",
color: colors.text,
marginBottom: 8,
},
cardText: {
fontSize: 16,
color: colors.textSecondary,
lineHeight: 22,
},

/* Primary Button */
primaryButton: {
backgroundColor: "#000",
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
marginBottom: 12,
},
primaryButtonText: {
color: "#fff",
fontSize: 18,
fontWeight: "bold",
},
/* Quick Receive Button */
quickReceiveButton: {
backgroundColor: "#10B981",
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
marginBottom: 12,
},
quickReceiveButtonText: {
color: "#fff",
fontSize: 18,
fontWeight: "600",
},
/* Primary Button */
primaryButton: {
backgroundColor: colors.primaryBtn,
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
marginBottom: 12,
},
primaryButtonText: {
color: colors.primaryBtnText,
fontSize: 18,
fontWeight: "bold",
},
/* Quick Receive Button */
quickReceiveButton: {
backgroundColor: colors.success,
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
marginBottom: 12,
},
quickReceiveButtonText: {
color: "#fff",
fontSize: 18,
fontWeight: "600",
},

/* Secondary Button */
secondaryButton: {
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
borderWidth: 1,
borderColor: "#000",
},
secondaryButtonText: {
color: "#000",
fontSize: 18,
fontWeight: "600",
},
});
/* Secondary Button */
secondaryButton: {
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 8,
width: "100%",
alignItems: "center",
borderWidth: 1,
borderColor: colors.secondaryBtnBorder,
},
secondaryButtonText: {
color: colors.secondaryBtnText,
fontSize: 18,
fontWeight: "600",
},
});
}
Loading