From b59d92510d23af5725e7c949b714ff50995dc932 Mon Sep 17 00:00:00 2001 From: imsophis Date: Fri, 22 May 2026 16:55:27 -0600 Subject: [PATCH] chore: clean initial expo structure --- frontend/src/app/explore.tsx | 180 ------------------ frontend/src/app/index.tsx | 98 ---------- .../src/components/animated-icon.module.css | 6 - frontend/src/components/animated-icon.tsx | 132 ------------- frontend/src/components/animated-icon.web.tsx | 108 ----------- frontend/src/components/app-tabs.tsx | 32 ---- frontend/src/components/app-tabs.web.tsx | 115 ----------- frontend/src/components/external-link.tsx | 25 --- frontend/src/components/hint-row.tsx | 35 ---- frontend/src/components/themed-text.tsx | 73 ------- frontend/src/components/themed-view.tsx | 16 -- frontend/src/components/ui/collapsible.tsx | 65 ------- frontend/src/components/web-badge.tsx | 43 ----- frontend/src/constants/colors.ts | 13 ++ 14 files changed, 13 insertions(+), 928 deletions(-) delete mode 100644 frontend/src/app/explore.tsx delete mode 100644 frontend/src/components/animated-icon.module.css delete mode 100644 frontend/src/components/animated-icon.tsx delete mode 100644 frontend/src/components/animated-icon.web.tsx delete mode 100644 frontend/src/components/app-tabs.tsx delete mode 100644 frontend/src/components/app-tabs.web.tsx delete mode 100644 frontend/src/components/external-link.tsx delete mode 100644 frontend/src/components/hint-row.tsx delete mode 100644 frontend/src/components/themed-text.tsx delete mode 100644 frontend/src/components/themed-view.tsx delete mode 100644 frontend/src/components/ui/collapsible.tsx delete mode 100644 frontend/src/components/web-badge.tsx create mode 100644 frontend/src/constants/colors.ts diff --git a/frontend/src/app/explore.tsx b/frontend/src/app/explore.tsx deleted file mode 100644 index 2934085..0000000 --- a/frontend/src/app/explore.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Image } from 'expo-image'; -import { SymbolView } from 'expo-symbols'; -import { Platform, Pressable, ScrollView, StyleSheet } from 'react-native'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; - -import { ExternalLink } from '@/components/external-link'; -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { Collapsible } from '@/components/ui/collapsible'; -import { WebBadge } from '@/components/web-badge'; -import { BottomTabInset, MaxContentWidth, Spacing } from '@/constants/theme'; -import { useTheme } from '@/hooks/use-theme'; - -export default function TabTwoScreen() { - const safeAreaInsets = useSafeAreaInsets(); - const insets = { - ...safeAreaInsets, - bottom: safeAreaInsets.bottom + BottomTabInset + Spacing.three, - }; - const theme = useTheme(); - - const contentPlatformStyle = Platform.select({ - android: { - paddingTop: insets.top, - paddingLeft: insets.left, - paddingRight: insets.right, - paddingBottom: insets.bottom, - }, - web: { - paddingTop: Spacing.six, - paddingBottom: Spacing.four, - }, - }); - - return ( - - - - Explore - - This starter app includes example{'\n'}code to help you get started. - - - - pressed && styles.pressed}> - - Expo documentation - - - - - - - - - - This app has two screens: src/app/index.tsx and{' '} - src/app/explore.tsx - - - The layout file in src/app/_layout.tsx sets up - the tab navigator. - - - Learn more - - - - - - - You can open this project on Android, iOS, and the web. To open the web version, - press w in the terminal running this - project. - - - - - - - - For static images, you can use the @2x and{' '} - @3x suffixes to provide files for different - screen densities. - - - - Learn more - - - - - - This template has light and dark mode support. The{' '} - useColorScheme() hook lets you inspect what the - user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - - This template includes an example of an animated component. The{' '} - src/components/ui/collapsible.tsx component uses - the powerful react-native-reanimated library to - animate opening this hint. - - - - {Platform.OS === 'web' && } - - - ); -} - -const styles = StyleSheet.create({ - scrollView: { - flex: 1, - }, - contentContainer: { - flexDirection: 'row', - justifyContent: 'center', - }, - container: { - maxWidth: MaxContentWidth, - flexGrow: 1, - }, - titleContainer: { - gap: Spacing.three, - alignItems: 'center', - paddingHorizontal: Spacing.four, - paddingVertical: Spacing.six, - }, - centerText: { - textAlign: 'center', - }, - pressed: { - opacity: 0.7, - }, - linkButton: { - flexDirection: 'row', - paddingHorizontal: Spacing.four, - paddingVertical: Spacing.two, - borderRadius: Spacing.five, - justifyContent: 'center', - gap: Spacing.one, - alignItems: 'center', - }, - sectionsWrapper: { - gap: Spacing.five, - paddingHorizontal: Spacing.four, - paddingTop: Spacing.three, - }, - collapsibleContent: { - alignItems: 'center', - }, - imageTutorial: { - width: '100%', - aspectRatio: 296 / 171, - borderRadius: Spacing.three, - marginTop: Spacing.two, - }, - imageReact: { - width: 100, - height: 100, - alignSelf: 'center', - }, -}); diff --git a/frontend/src/app/index.tsx b/frontend/src/app/index.tsx index 8ec3e6f..e69de29 100644 --- a/frontend/src/app/index.tsx +++ b/frontend/src/app/index.tsx @@ -1,98 +0,0 @@ -import * as Device from 'expo-device'; -import { Platform, StyleSheet } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; - -import { AnimatedIcon } from '@/components/animated-icon'; -import { HintRow } from '@/components/hint-row'; -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { WebBadge } from '@/components/web-badge'; -import { BottomTabInset, MaxContentWidth, Spacing } from '@/constants/theme'; - -function getDevMenuHint() { - if (Platform.OS === 'web') { - return use browser devtools; - } - if (Device.isDevice) { - return ( - - shake device or press m in terminal - - ); - } - const shortcut = Platform.OS === 'android' ? 'cmd+m (or ctrl+m)' : 'cmd+d'; - return ( - - press {shortcut} - - ); -} - -export default function HomeScreen() { - return ( - - - - - - Welcome to Expo - - - - - get started - - - - src/app/index.tsx} - /> - - npm run reset-project} - /> - - - {Platform.OS === 'web' && } - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - flexDirection: 'row', - }, - safeArea: { - flex: 1, - paddingHorizontal: Spacing.four, - alignItems: 'center', - gap: Spacing.three, - paddingBottom: BottomTabInset + Spacing.three, - maxWidth: MaxContentWidth, - }, - heroSection: { - alignItems: 'center', - justifyContent: 'center', - flex: 1, - paddingHorizontal: Spacing.four, - gap: Spacing.four, - }, - title: { - textAlign: 'center', - }, - code: { - textTransform: 'uppercase', - }, - stepContainer: { - gap: Spacing.three, - alignSelf: 'stretch', - paddingHorizontal: Spacing.three, - paddingVertical: Spacing.four, - borderRadius: Spacing.four, - }, -}); diff --git a/frontend/src/components/animated-icon.module.css b/frontend/src/components/animated-icon.module.css deleted file mode 100644 index f8156fe..0000000 --- a/frontend/src/components/animated-icon.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.expoLogoBackground { - background-image: linear-gradient(180deg, #3c9ffe, #0274df); - border-radius: 40px; - width: 128px; - height: 128px; -} diff --git a/frontend/src/components/animated-icon.tsx b/frontend/src/components/animated-icon.tsx deleted file mode 100644 index 9d900a8..0000000 --- a/frontend/src/components/animated-icon.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { Image } from 'expo-image'; -import { useState } from 'react'; -import { Dimensions, StyleSheet, View } from 'react-native'; -import Animated, { Easing, Keyframe } from 'react-native-reanimated'; -import { scheduleOnRN } from 'react-native-worklets'; - -const INITIAL_SCALE_FACTOR = Dimensions.get('screen').height / 90; -const DURATION = 600; - -export function AnimatedSplashOverlay() { - const [visible, setVisible] = useState(true); - - if (!visible) return null; - - const splashKeyframe = new Keyframe({ - 0: { - transform: [{ scale: INITIAL_SCALE_FACTOR }], - opacity: 1, - }, - 20: { - opacity: 1, - }, - 70: { - opacity: 0, - easing: Easing.elastic(0.7), - }, - 100: { - opacity: 0, - transform: [{ scale: 1 }], - easing: Easing.elastic(0.7), - }, - }); - - return ( - { - 'worklet'; - if (finished) { - scheduleOnRN(setVisible, false); - } - })} - style={styles.backgroundSolidColor} - /> - ); -} - -const keyframe = new Keyframe({ - 0: { - transform: [{ scale: INITIAL_SCALE_FACTOR }], - }, - 100: { - transform: [{ scale: 1 }], - easing: Easing.elastic(0.7), - }, -}); - -const logoKeyframe = new Keyframe({ - 0: { - transform: [{ scale: 1.3 }], - opacity: 0, - }, - 40: { - transform: [{ scale: 1.3 }], - opacity: 0, - easing: Easing.elastic(0.7), - }, - 100: { - opacity: 1, - transform: [{ scale: 1 }], - easing: Easing.elastic(0.7), - }, -}); - -const glowKeyframe = new Keyframe({ - 0: { - transform: [{ rotateZ: '0deg' }], - }, - 100: { - transform: [{ rotateZ: '7200deg' }], - }, -}); - -export function AnimatedIcon() { - return ( - - - - - - - - - - - ); -} - -const styles = StyleSheet.create({ - imageContainer: { - justifyContent: 'center', - alignItems: 'center', - }, - glow: { - width: 201, - height: 201, - position: 'absolute', - }, - iconContainer: { - justifyContent: 'center', - alignItems: 'center', - width: 128, - height: 128, - zIndex: 100, - }, - image: { - position: 'absolute', - width: 76, - height: 71, - }, - background: { - borderRadius: 40, - experimental_backgroundImage: `linear-gradient(180deg, #3C9FFE, #0274DF)`, - width: 128, - height: 128, - position: 'absolute', - }, - backgroundSolidColor: { - ...StyleSheet.absoluteFill, - backgroundColor: '#208AEF', - zIndex: 1000, - }, -}); diff --git a/frontend/src/components/animated-icon.web.tsx b/frontend/src/components/animated-icon.web.tsx deleted file mode 100644 index dfbb1fd..0000000 --- a/frontend/src/components/animated-icon.web.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { Image } from 'expo-image'; -import { StyleSheet, View } from 'react-native'; -import Animated, { Keyframe, Easing } from 'react-native-reanimated'; - -import classes from './animated-icon.module.css'; -const DURATION = 300; - -export function AnimatedSplashOverlay() { - return null; -} - -const keyframe = new Keyframe({ - 0: { - transform: [{ scale: 0 }], - }, - 60: { - transform: [{ scale: 1.2 }], - easing: Easing.elastic(1.2), - }, - 100: { - transform: [{ scale: 1 }], - easing: Easing.elastic(1.2), - }, -}); - -const logoKeyframe = new Keyframe({ - 0: { - opacity: 0, - }, - 60: { - transform: [{ scale: 1.2 }], - opacity: 0, - easing: Easing.elastic(1.2), - }, - 100: { - transform: [{ scale: 1 }], - opacity: 1, - easing: Easing.elastic(1.2), - }, -}); - -const glowKeyframe = new Keyframe({ - 0: { - transform: [{ rotateZ: '-180deg' }, { scale: 0.8 }], - opacity: 0, - }, - [DURATION / 1000]: { - transform: [{ rotateZ: '0deg' }, { scale: 1 }], - opacity: 1, - easing: Easing.elastic(0.7), - }, - 100: { - transform: [{ rotateZ: '7200deg' }], - }, -}); - -export function AnimatedIcon() { - return ( - - - - - - -
- - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - alignItems: 'center', - width: '100%', - zIndex: 1000, - position: 'absolute', - top: 128 / 2 + 138, - }, - imageContainer: { - justifyContent: 'center', - alignItems: 'center', - }, - glow: { - width: 201, - height: 201, - position: 'absolute', - }, - iconContainer: { - justifyContent: 'center', - alignItems: 'center', - width: 128, - height: 128, - }, - image: { - position: 'absolute', - width: 76, - height: 71, - }, - background: { - width: 128, - height: 128, - position: 'absolute', - }, -}); diff --git a/frontend/src/components/app-tabs.tsx b/frontend/src/components/app-tabs.tsx deleted file mode 100644 index 80719bc..0000000 --- a/frontend/src/components/app-tabs.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { NativeTabs } from 'expo-router/unstable-native-tabs'; -import { useColorScheme } from 'react-native'; - -import { Colors } from '@/constants/theme'; - -export default function AppTabs() { - const scheme = useColorScheme(); - const colors = Colors[scheme === 'unspecified' ? 'light' : scheme]; - - return ( - - - Home - - - - - Explore - - - - ); -} diff --git a/frontend/src/components/app-tabs.web.tsx b/frontend/src/components/app-tabs.web.tsx deleted file mode 100644 index ca2787d..0000000 --- a/frontend/src/components/app-tabs.web.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { - Tabs, - TabList, - TabTrigger, - TabSlot, - TabTriggerSlotProps, - TabListProps, -} from 'expo-router/ui'; -import { SymbolView } from 'expo-symbols'; -import { Pressable, useColorScheme, View, StyleSheet } from 'react-native'; - -import { ExternalLink } from './external-link'; -import { ThemedText } from './themed-text'; -import { ThemedView } from './themed-view'; - -import { Colors, MaxContentWidth, Spacing } from '@/constants/theme'; - -export default function AppTabs() { - return ( - - - - - - Home - - - Explore - - - - - ); -} - -export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps) { - return ( - pressed && styles.pressed}> - - - {children} - - - - ); -} - -export function CustomTabList(props: TabListProps) { - const scheme = useColorScheme(); - const colors = Colors[scheme === 'unspecified' ? 'light' : scheme]; - - return ( - - - - Expo Starter - - - {props.children} - - - - Docs - - - - - - ); -} - -const styles = StyleSheet.create({ - tabListContainer: { - position: 'absolute', - width: '100%', - padding: Spacing.three, - justifyContent: 'center', - alignItems: 'center', - flexDirection: 'row', - }, - innerContainer: { - paddingVertical: Spacing.two, - paddingHorizontal: Spacing.five, - borderRadius: Spacing.five, - flexDirection: 'row', - alignItems: 'center', - flexGrow: 1, - gap: Spacing.two, - maxWidth: MaxContentWidth, - }, - brandText: { - marginRight: 'auto', - }, - pressed: { - opacity: 0.7, - }, - tabButtonView: { - paddingVertical: Spacing.one, - paddingHorizontal: Spacing.three, - borderRadius: Spacing.three, - }, - externalPressable: { - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - gap: Spacing.one, - marginLeft: Spacing.three, - }, -}); diff --git a/frontend/src/components/external-link.tsx b/frontend/src/components/external-link.tsx deleted file mode 100644 index 883e515..0000000 --- a/frontend/src/components/external-link.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Href, Link } from 'expo-router'; -import { openBrowserAsync, WebBrowserPresentationStyle } from 'expo-web-browser'; -import { type ComponentProps } from 'react'; - -type Props = Omit, 'href'> & { href: Href & string }; - -export function ExternalLink({ href, ...rest }: Props) { - return ( - { - if (process.env.EXPO_OS !== 'web') { - // Prevent the default behavior of linking to the default browser on native. - event.preventDefault(); - // Open the link in an in-app browser. - await openBrowserAsync(href, { - presentationStyle: WebBrowserPresentationStyle.AUTOMATIC, - }); - } - }} - /> - ); -} diff --git a/frontend/src/components/hint-row.tsx b/frontend/src/components/hint-row.tsx deleted file mode 100644 index acf4dc5..0000000 --- a/frontend/src/components/hint-row.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import type { ReactNode } from 'react'; -import { View, StyleSheet } from 'react-native'; - -import { ThemedText } from './themed-text'; -import { ThemedView } from './themed-view'; - -import { Spacing } from '@/constants/theme'; - -type HintRowProps = { - title?: string; - hint?: ReactNode; -}; - -export function HintRow({ title = 'Try editing', hint = 'app/index.tsx' }: HintRowProps) { - return ( - - {title} - - {hint} - - - ); -} - -const styles = StyleSheet.create({ - stepRow: { - flexDirection: 'row', - justifyContent: 'space-between', - }, - codeSnippet: { - borderRadius: Spacing.two, - paddingVertical: Spacing.half, - paddingHorizontal: Spacing.two, - }, -}); diff --git a/frontend/src/components/themed-text.tsx b/frontend/src/components/themed-text.tsx deleted file mode 100644 index 799c8b1..0000000 --- a/frontend/src/components/themed-text.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Platform, StyleSheet, Text, type TextProps } from 'react-native'; - -import { Fonts, ThemeColor } from '@/constants/theme'; -import { useTheme } from '@/hooks/use-theme'; - -export type ThemedTextProps = TextProps & { - type?: 'default' | 'title' | 'small' | 'smallBold' | 'subtitle' | 'link' | 'linkPrimary' | 'code'; - themeColor?: ThemeColor; -}; - -export function ThemedText({ style, type = 'default', themeColor, ...rest }: ThemedTextProps) { - const theme = useTheme(); - - return ( - - ); -} - -const styles = StyleSheet.create({ - small: { - fontSize: 14, - lineHeight: 20, - fontWeight: 500, - }, - smallBold: { - fontSize: 14, - lineHeight: 20, - fontWeight: 700, - }, - default: { - fontSize: 16, - lineHeight: 24, - fontWeight: 500, - }, - title: { - fontSize: 48, - fontWeight: 600, - lineHeight: 52, - }, - subtitle: { - fontSize: 32, - lineHeight: 44, - fontWeight: 600, - }, - link: { - lineHeight: 30, - fontSize: 14, - }, - linkPrimary: { - lineHeight: 30, - fontSize: 14, - color: '#3c87f7', - }, - code: { - fontFamily: Fonts.mono, - fontWeight: Platform.select({ android: 700 }) ?? 500, - fontSize: 12, - }, -}); diff --git a/frontend/src/components/themed-view.tsx b/frontend/src/components/themed-view.tsx deleted file mode 100644 index c710df9..0000000 --- a/frontend/src/components/themed-view.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { View, type ViewProps } from 'react-native'; - -import { ThemeColor } from '@/constants/theme'; -import { useTheme } from '@/hooks/use-theme'; - -export type ThemedViewProps = ViewProps & { - lightColor?: string; - darkColor?: string; - type?: ThemeColor; -}; - -export function ThemedView({ style, lightColor, darkColor, type, ...otherProps }: ThemedViewProps) { - const theme = useTheme(); - - return ; -} diff --git a/frontend/src/components/ui/collapsible.tsx b/frontend/src/components/ui/collapsible.tsx deleted file mode 100644 index d0d745b..0000000 --- a/frontend/src/components/ui/collapsible.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { SymbolView } from 'expo-symbols'; -import { PropsWithChildren, useState } from 'react'; -import { Pressable, StyleSheet } from 'react-native'; -import Animated, { FadeIn } from 'react-native-reanimated'; - -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { Spacing } from '@/constants/theme'; -import { useTheme } from '@/hooks/use-theme'; - -export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { - const [isOpen, setIsOpen] = useState(false); - const theme = useTheme(); - - return ( - - [styles.heading, pressed && styles.pressedHeading]} - onPress={() => setIsOpen((value) => !value)}> - - - - - {title} - - {isOpen && ( - - - {children} - - - )} - - ); -} - -const styles = StyleSheet.create({ - heading: { - flexDirection: 'row', - alignItems: 'center', - gap: Spacing.two, - }, - pressedHeading: { - opacity: 0.7, - }, - button: { - width: Spacing.four, - height: Spacing.four, - borderRadius: 12, - justifyContent: 'center', - alignItems: 'center', - }, - content: { - marginTop: Spacing.three, - borderRadius: Spacing.three, - marginLeft: Spacing.four, - padding: Spacing.four, - }, -}); diff --git a/frontend/src/components/web-badge.tsx b/frontend/src/components/web-badge.tsx deleted file mode 100644 index 6667898..0000000 --- a/frontend/src/components/web-badge.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { version } from 'expo/package.json'; -import { Image } from 'expo-image'; -import { useColorScheme, StyleSheet } from 'react-native'; - -import { ThemedText } from './themed-text'; -import { ThemedView } from './themed-view'; - -import { Spacing } from '@/constants/theme'; - -export function WebBadge() { - const scheme = useColorScheme(); - - return ( - - - v{version} - - - - ); -} - -const styles = StyleSheet.create({ - container: { - padding: Spacing.five, - alignItems: 'center', - gap: Spacing.two, - }, - versionText: { - textAlign: 'center', - }, - badgeImage: { - width: 123, - aspectRatio: 123 / 24, - }, -}); diff --git a/frontend/src/constants/colors.ts b/frontend/src/constants/colors.ts new file mode 100644 index 0000000..adafd5f --- /dev/null +++ b/frontend/src/constants/colors.ts @@ -0,0 +1,13 @@ +export const COLORS = { + primary: "#0E8A61", + background: "#F5F7F5", + card: "#FFFFFF", + text: "#1A1A1A", + subtitle: "#6B7280", + + success: "#22C55E", + warning: "#FACC15", + danger: "#EF4444", + + border: "#E5E7EB", +}; \ No newline at end of file