tambahan
This commit is contained in:
14
app/(application)/_layout.tsx
Normal file
14
app/(application)/_layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { Headers } from "@/constants/Headers";
|
||||||
|
import { Stack } from "expo-router";
|
||||||
|
import { StatusBar } from 'expo-status-bar';
|
||||||
|
|
||||||
|
export default function RootLayout() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack screenOptions={Headers.shadow}>
|
||||||
|
<Stack.Screen name="home" options={{ title: 'Home' }} />
|
||||||
|
</Stack>
|
||||||
|
<StatusBar style="light" />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
22
app/(application)/home.tsx
Normal file
22
app/(application)/home.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import CaraouselHome from "@/components/home/carouselHome";
|
||||||
|
import { HeaderRightHome } from "@/components/home/headerRightHome";
|
||||||
|
import { Stack } from "expo-router";
|
||||||
|
import { SafeAreaView, ScrollView } from "react-native";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<SafeAreaView>
|
||||||
|
<Stack.Screen
|
||||||
|
options={{
|
||||||
|
title: 'Home',
|
||||||
|
headerLeft: () => <></>,
|
||||||
|
headerTitle: 'Darmasaba',
|
||||||
|
headerRight: () => <HeaderRightHome />
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ScrollView>
|
||||||
|
<CaraouselHome/>
|
||||||
|
</ScrollView>
|
||||||
|
</SafeAreaView>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { Tabs } from 'expo-router';
|
|
||||||
import React from 'react';
|
|
||||||
import { Platform } from 'react-native';
|
|
||||||
|
|
||||||
import { HapticTab } from '@/components/HapticTab';
|
|
||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
|
||||||
import TabBarBackground from '@/components/ui/TabBarBackground';
|
|
||||||
import { Colors } from '@/constants/Colors';
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
export default function TabLayout() {
|
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tabs
|
|
||||||
screenOptions={{
|
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
|
||||||
headerShown: false,
|
|
||||||
tabBarButton: HapticTab,
|
|
||||||
tabBarBackground: TabBarBackground,
|
|
||||||
tabBarStyle: Platform.select({
|
|
||||||
ios: {
|
|
||||||
// Use a transparent background on iOS to show the blur effect
|
|
||||||
position: 'absolute',
|
|
||||||
},
|
|
||||||
default: {},
|
|
||||||
}),
|
|
||||||
}}>
|
|
||||||
<Tabs.Screen
|
|
||||||
name="index"
|
|
||||||
options={{
|
|
||||||
title: 'Home',
|
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Tabs.Screen
|
|
||||||
name="explore"
|
|
||||||
options={{
|
|
||||||
title: 'Explore',
|
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tabs>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
import { StyleSheet, Image, Platform } from 'react-native';
|
|
||||||
|
|
||||||
import { Collapsible } from '@/components/Collapsible';
|
|
||||||
import { ExternalLink } from '@/components/ExternalLink';
|
|
||||||
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
|
||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
|
||||||
|
|
||||||
export default function TabTwoScreen() {
|
|
||||||
return (
|
|
||||||
<ParallaxScrollView
|
|
||||||
headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
|
|
||||||
headerImage={
|
|
||||||
<IconSymbol
|
|
||||||
size={310}
|
|
||||||
color="#808080"
|
|
||||||
name="chevron.left.forwardslash.chevron.right"
|
|
||||||
style={styles.headerImage}
|
|
||||||
/>
|
|
||||||
}>
|
|
||||||
<ThemedView style={styles.titleContainer}>
|
|
||||||
<ThemedText type="title">Explore</ThemedText>
|
|
||||||
</ThemedView>
|
|
||||||
<ThemedText>This app includes example code to help you get started.</ThemedText>
|
|
||||||
<Collapsible title="File-based routing">
|
|
||||||
<ThemedText>
|
|
||||||
This app has two screens:{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
|
|
||||||
</ThemedText>
|
|
||||||
<ThemedText>
|
|
||||||
The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
|
|
||||||
sets up the tab navigator.
|
|
||||||
</ThemedText>
|
|
||||||
<ExternalLink href="https://docs.expo.dev/router/introduction">
|
|
||||||
<ThemedText type="link">Learn more</ThemedText>
|
|
||||||
</ExternalLink>
|
|
||||||
</Collapsible>
|
|
||||||
<Collapsible title="Android, iOS, and web support">
|
|
||||||
<ThemedText>
|
|
||||||
You can open this project on Android, iOS, and the web. To open the web version, press{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
|
|
||||||
</ThemedText>
|
|
||||||
</Collapsible>
|
|
||||||
<Collapsible title="Images">
|
|
||||||
<ThemedText>
|
|
||||||
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
|
|
||||||
different screen densities
|
|
||||||
</ThemedText>
|
|
||||||
<Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
|
|
||||||
<ExternalLink href="https://reactnative.dev/docs/images">
|
|
||||||
<ThemedText type="link">Learn more</ThemedText>
|
|
||||||
</ExternalLink>
|
|
||||||
</Collapsible>
|
|
||||||
<Collapsible title="Custom fonts">
|
|
||||||
<ThemedText>
|
|
||||||
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
|
|
||||||
<ThemedText style={{ fontFamily: 'SpaceMono' }}>
|
|
||||||
custom fonts such as this one.
|
|
||||||
</ThemedText>
|
|
||||||
</ThemedText>
|
|
||||||
<ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
|
|
||||||
<ThemedText type="link">Learn more</ThemedText>
|
|
||||||
</ExternalLink>
|
|
||||||
</Collapsible>
|
|
||||||
<Collapsible title="Light and dark mode components">
|
|
||||||
<ThemedText>
|
|
||||||
This template has light and dark mode support. The{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
|
|
||||||
what the user's current color scheme is, and so you can adjust UI colors accordingly.
|
|
||||||
</ThemedText>
|
|
||||||
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
|
|
||||||
<ThemedText type="link">Learn more</ThemedText>
|
|
||||||
</ExternalLink>
|
|
||||||
</Collapsible>
|
|
||||||
<Collapsible title="Animations">
|
|
||||||
<ThemedText>
|
|
||||||
This template includes an example of an animated component. The{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
|
|
||||||
the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
|
|
||||||
library to create a waving hand animation.
|
|
||||||
</ThemedText>
|
|
||||||
{Platform.select({
|
|
||||||
ios: (
|
|
||||||
<ThemedText>
|
|
||||||
The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
|
|
||||||
component provides a parallax effect for the header image.
|
|
||||||
</ThemedText>
|
|
||||||
),
|
|
||||||
})}
|
|
||||||
</Collapsible>
|
|
||||||
</ParallaxScrollView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
headerImage: {
|
|
||||||
color: '#808080',
|
|
||||||
bottom: -90,
|
|
||||||
left: -35,
|
|
||||||
position: 'absolute',
|
|
||||||
},
|
|
||||||
titleContainer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
gap: 8,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
import { Image, StyleSheet, Platform } from 'react-native';
|
|
||||||
|
|
||||||
import { HelloWave } from '@/components/HelloWave';
|
|
||||||
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
|
||||||
|
|
||||||
export default function HomeScreen() {
|
|
||||||
return (
|
|
||||||
<ParallaxScrollView
|
|
||||||
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
|
|
||||||
headerImage={
|
|
||||||
<Image
|
|
||||||
source={require('@/assets/images/partial-react-logo.png')}
|
|
||||||
style={styles.reactLogo}
|
|
||||||
/>
|
|
||||||
}>
|
|
||||||
<ThemedView style={styles.titleContainer}>
|
|
||||||
<ThemedText type="title">Welcome!</ThemedText>
|
|
||||||
<HelloWave />
|
|
||||||
</ThemedView>
|
|
||||||
<ThemedView style={styles.stepContainer}>
|
|
||||||
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
|
|
||||||
<ThemedText>
|
|
||||||
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
|
|
||||||
Press{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">
|
|
||||||
{Platform.select({
|
|
||||||
ios: 'cmd + d',
|
|
||||||
android: 'cmd + m',
|
|
||||||
web: 'F12'
|
|
||||||
})}
|
|
||||||
</ThemedText>{' '}
|
|
||||||
to open developer tools.
|
|
||||||
</ThemedText>
|
|
||||||
</ThemedView>
|
|
||||||
<ThemedView style={styles.stepContainer}>
|
|
||||||
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
|
|
||||||
<ThemedText>
|
|
||||||
Tap the Explore tab to learn more about what's included in this starter app.
|
|
||||||
</ThemedText>
|
|
||||||
</ThemedView>
|
|
||||||
<ThemedView style={styles.stepContainer}>
|
|
||||||
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
|
|
||||||
<ThemedText>
|
|
||||||
When you're ready, run{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
|
|
||||||
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
|
|
||||||
</ThemedText>
|
|
||||||
</ThemedView>
|
|
||||||
</ParallaxScrollView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
titleContainer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 8,
|
|
||||||
},
|
|
||||||
stepContainer: {
|
|
||||||
gap: 8,
|
|
||||||
marginBottom: 8,
|
|
||||||
},
|
|
||||||
reactLogo: {
|
|
||||||
height: 178,
|
|
||||||
width: 290,
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { Link, Stack } from 'expo-router';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
|
||||||
|
|
||||||
export default function NotFoundScreen() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Stack.Screen options={{ title: 'Oops!' }} />
|
|
||||||
<ThemedView style={styles.container}>
|
|
||||||
<ThemedText type="title">This screen doesn't exist.</ThemedText>
|
|
||||||
<Link href="/" style={styles.link}>
|
|
||||||
<ThemedText type="link">Go to home screen!</ThemedText>
|
|
||||||
</Link>
|
|
||||||
</ThemedView>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
padding: 20,
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
marginTop: 15,
|
|
||||||
paddingVertical: 15,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
|
||||||
import { useFonts } from 'expo-font';
|
import { useFonts } from 'expo-font';
|
||||||
import { Stack } from 'expo-router';
|
import { Stack } from 'expo-router';
|
||||||
import * as SplashScreen from 'expo-splash-screen';
|
import * as SplashScreen from 'expo-splash-screen';
|
||||||
@@ -6,13 +5,10 @@ import { StatusBar } from 'expo-status-bar';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import 'react-native-reanimated';
|
import 'react-native-reanimated';
|
||||||
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
||||||
SplashScreen.preventAutoHideAsync();
|
SplashScreen.preventAutoHideAsync();
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
const [loaded] = useFonts({
|
const [loaded] = useFonts({
|
||||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
||||||
});
|
});
|
||||||
@@ -28,12 +24,14 @@ export default function RootLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="+not-found" />
|
<Stack.Screen name="verification" options={{ headerShown: false }} />
|
||||||
|
<Stack.Screen name="(application)" options={{ headerShown: false }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
<StatusBar style="auto" />
|
<StatusBar style="auto" />
|
||||||
</ThemeProvider>
|
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
26
app/index.tsx
Normal file
26
app/index.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { ButtonForm } from "@/components/buttonForm";
|
||||||
|
import { InputForm } from "@/components/inputForm";
|
||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { Image, Text, View } from "react-native";
|
||||||
|
|
||||||
|
export default function Index() {
|
||||||
|
return (
|
||||||
|
<View style={Styles.wrapLogin} >
|
||||||
|
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||||
|
<Image
|
||||||
|
source={require("../assets/images/splash-icon.png")}
|
||||||
|
style={{ width: 130, height: 130 }}
|
||||||
|
/>
|
||||||
|
<Text style={[Styles.textSubtitle]}>PERBEKEL DARMASABA</Text>
|
||||||
|
</View>
|
||||||
|
<InputForm
|
||||||
|
type="numeric"
|
||||||
|
placeholder="XXX-XXX-XXXX"
|
||||||
|
round
|
||||||
|
itemLeft={<Text>+62</Text>}
|
||||||
|
info="Kami akan mengirim kode verifikasi melalui WhatsApp, guna mengonfirmasikan nomor Anda." />
|
||||||
|
<ButtonForm text="MASUK" onPress={() => { router.push("/verification") }} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
54
app/verification.tsx
Normal file
54
app/verification.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { ButtonForm } from "@/components/buttonForm";
|
||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Image, SafeAreaView, Text, View } from "react-native";
|
||||||
|
import { CodeField, Cursor, useBlurOnFulfill, useClearByFocusCell, } from 'react-native-confirmation-code-field';
|
||||||
|
|
||||||
|
export default function Index() {
|
||||||
|
const [value, setValue] = useState('');
|
||||||
|
const ref = useBlurOnFulfill({ value, cellCount: 4 });
|
||||||
|
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={Styles.wrapLogin} >
|
||||||
|
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||||
|
<Image
|
||||||
|
source={require("../assets/images/splash-icon.png")}
|
||||||
|
style={{ width: 130, height: 130 }}
|
||||||
|
/>
|
||||||
|
<Text style={[Styles.textSubtitle]}>PERBEKEL DARMASABA</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[Styles.mb30]}>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold]}>Verifikasi Nomor Telepon</Text>
|
||||||
|
<Text style={[Styles.textMediumNormal]}>Masukkan kode yang kami kirimkan melalui WhatsApp</Text>
|
||||||
|
<Text style={[Styles.textMediumSemiBold]}>+628980185458</Text>
|
||||||
|
</View>
|
||||||
|
<CodeField
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
value={value}
|
||||||
|
rootStyle={{ width: '80%', alignSelf: 'center' }}
|
||||||
|
onChangeText={setValue}
|
||||||
|
cellCount={4}
|
||||||
|
keyboardType="number-pad"
|
||||||
|
renderCell={({ index, symbol, isFocused }) => (
|
||||||
|
<Text
|
||||||
|
key={index}
|
||||||
|
style={[Styles.verificationCell, isFocused && Styles.verificationFocusCell]}
|
||||||
|
onLayout={getCellOnLayoutHandler(index)}>
|
||||||
|
{symbol || (isFocused ? <Cursor /> : null)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<ButtonForm text="SUBMIT" onPress={() => { router.push("/home") }} />
|
||||||
|
<Text style={[Styles.textInformation, Styles.cDefault, { textAlign: 'center' }]}>
|
||||||
|
Tidak Menerima kode verifikasi? Kirim Ulang
|
||||||
|
</Text>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 37 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 37 KiB |
BIN
assets/images/user.jpeg
Normal file
BIN
assets/images/user.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
@@ -1,45 +0,0 @@
|
|||||||
import { PropsWithChildren, useState } from 'react';
|
|
||||||
import { StyleSheet, TouchableOpacity } from 'react-native';
|
|
||||||
|
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
|
||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
|
||||||
import { Colors } from '@/constants/Colors';
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const theme = useColorScheme() ?? 'light';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemedView>
|
|
||||||
<TouchableOpacity
|
|
||||||
style={styles.heading}
|
|
||||||
onPress={() => setIsOpen((value) => !value)}
|
|
||||||
activeOpacity={0.8}>
|
|
||||||
<IconSymbol
|
|
||||||
name="chevron.right"
|
|
||||||
size={18}
|
|
||||||
weight="medium"
|
|
||||||
color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
|
|
||||||
style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ThemedText type="defaultSemiBold">{title}</ThemedText>
|
|
||||||
</TouchableOpacity>
|
|
||||||
{isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
|
|
||||||
</ThemedView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
heading: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 6,
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
marginTop: 6,
|
|
||||||
marginLeft: 24,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Link } from 'expo-router';
|
|
||||||
import { openBrowserAsync } from 'expo-web-browser';
|
|
||||||
import { type ComponentProps } from 'react';
|
|
||||||
import { Platform } from 'react-native';
|
|
||||||
|
|
||||||
type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: string };
|
|
||||||
|
|
||||||
export function ExternalLink({ href, ...rest }: Props) {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
target="_blank"
|
|
||||||
{...rest}
|
|
||||||
href={href}
|
|
||||||
onPress={async (event) => {
|
|
||||||
if (Platform.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);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs';
|
|
||||||
import { PlatformPressable } from '@react-navigation/elements';
|
|
||||||
import * as Haptics from 'expo-haptics';
|
|
||||||
|
|
||||||
export function HapticTab(props: BottomTabBarButtonProps) {
|
|
||||||
return (
|
|
||||||
<PlatformPressable
|
|
||||||
{...props}
|
|
||||||
onPressIn={(ev) => {
|
|
||||||
if (process.env.EXPO_OS === 'ios') {
|
|
||||||
// Add a soft haptic feedback when pressing down on the tabs.
|
|
||||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
|
||||||
}
|
|
||||||
props.onPressIn?.(ev);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
import Animated, {
|
|
||||||
useSharedValue,
|
|
||||||
useAnimatedStyle,
|
|
||||||
withTiming,
|
|
||||||
withRepeat,
|
|
||||||
withSequence,
|
|
||||||
} from 'react-native-reanimated';
|
|
||||||
|
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
|
||||||
|
|
||||||
export function HelloWave() {
|
|
||||||
const rotationAnimation = useSharedValue(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
rotationAnimation.value = withRepeat(
|
|
||||||
withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })),
|
|
||||||
4 // Run the animation 4 times
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const animatedStyle = useAnimatedStyle(() => ({
|
|
||||||
transform: [{ rotate: `${rotationAnimation.value}deg` }],
|
|
||||||
}));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Animated.View style={animatedStyle}>
|
|
||||||
<ThemedText style={styles.text}>👋</ThemedText>
|
|
||||||
</Animated.View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
text: {
|
|
||||||
fontSize: 28,
|
|
||||||
lineHeight: 32,
|
|
||||||
marginTop: -6,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
import type { PropsWithChildren, ReactElement } from 'react';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
import Animated, {
|
|
||||||
interpolate,
|
|
||||||
useAnimatedRef,
|
|
||||||
useAnimatedStyle,
|
|
||||||
useScrollViewOffset,
|
|
||||||
} from 'react-native-reanimated';
|
|
||||||
|
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
|
||||||
import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
const HEADER_HEIGHT = 250;
|
|
||||||
|
|
||||||
type Props = PropsWithChildren<{
|
|
||||||
headerImage: ReactElement;
|
|
||||||
headerBackgroundColor: { dark: string; light: string };
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export default function ParallaxScrollView({
|
|
||||||
children,
|
|
||||||
headerImage,
|
|
||||||
headerBackgroundColor,
|
|
||||||
}: Props) {
|
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
|
||||||
const scrollRef = useAnimatedRef<Animated.ScrollView>();
|
|
||||||
const scrollOffset = useScrollViewOffset(scrollRef);
|
|
||||||
const bottom = useBottomTabOverflow();
|
|
||||||
const headerAnimatedStyle = useAnimatedStyle(() => {
|
|
||||||
return {
|
|
||||||
transform: [
|
|
||||||
{
|
|
||||||
translateY: interpolate(
|
|
||||||
scrollOffset.value,
|
|
||||||
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
|
|
||||||
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemedView style={styles.container}>
|
|
||||||
<Animated.ScrollView
|
|
||||||
ref={scrollRef}
|
|
||||||
scrollEventThrottle={16}
|
|
||||||
scrollIndicatorInsets={{ bottom }}
|
|
||||||
contentContainerStyle={{ paddingBottom: bottom }}>
|
|
||||||
<Animated.View
|
|
||||||
style={[
|
|
||||||
styles.header,
|
|
||||||
{ backgroundColor: headerBackgroundColor[colorScheme] },
|
|
||||||
headerAnimatedStyle,
|
|
||||||
]}>
|
|
||||||
{headerImage}
|
|
||||||
</Animated.View>
|
|
||||||
<ThemedView style={styles.content}>{children}</ThemedView>
|
|
||||||
</Animated.ScrollView>
|
|
||||||
</ThemedView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
height: HEADER_HEIGHT,
|
|
||||||
overflow: 'hidden',
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
flex: 1,
|
|
||||||
padding: 32,
|
|
||||||
gap: 16,
|
|
||||||
overflow: 'hidden',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import { Text, type TextProps, StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { useThemeColor } from '@/hooks/useThemeColor';
|
|
||||||
|
|
||||||
export type ThemedTextProps = TextProps & {
|
|
||||||
lightColor?: string;
|
|
||||||
darkColor?: string;
|
|
||||||
type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ThemedText({
|
|
||||||
style,
|
|
||||||
lightColor,
|
|
||||||
darkColor,
|
|
||||||
type = 'default',
|
|
||||||
...rest
|
|
||||||
}: ThemedTextProps) {
|
|
||||||
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
{ color },
|
|
||||||
type === 'default' ? styles.default : undefined,
|
|
||||||
type === 'title' ? styles.title : undefined,
|
|
||||||
type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
|
|
||||||
type === 'subtitle' ? styles.subtitle : undefined,
|
|
||||||
type === 'link' ? styles.link : undefined,
|
|
||||||
style,
|
|
||||||
]}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
default: {
|
|
||||||
fontSize: 16,
|
|
||||||
lineHeight: 24,
|
|
||||||
},
|
|
||||||
defaultSemiBold: {
|
|
||||||
fontSize: 16,
|
|
||||||
lineHeight: 24,
|
|
||||||
fontWeight: '600',
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 32,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
lineHeight: 32,
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
lineHeight: 30,
|
|
||||||
fontSize: 16,
|
|
||||||
color: '#0a7ea4',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { View, type ViewProps } from 'react-native';
|
|
||||||
|
|
||||||
import { useThemeColor } from '@/hooks/useThemeColor';
|
|
||||||
|
|
||||||
export type ThemedViewProps = ViewProps & {
|
|
||||||
lightColor?: string;
|
|
||||||
darkColor?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
|
|
||||||
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
|
||||||
|
|
||||||
return <View style={[{ backgroundColor }, style]} {...otherProps} />;
|
|
||||||
}
|
|
||||||
15
components/buttonForm.tsx
Normal file
15
components/buttonForm.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { Text, TouchableOpacity } from "react-native";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
text: string;
|
||||||
|
onPress: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ButtonForm({ text, onPress }: Props) {
|
||||||
|
return (
|
||||||
|
<TouchableOpacity style={[Styles.btnRound, { marginTop: 30 }]} onPress={onPress}>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold, Styles.cWhite]}>{text}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
components/buttonHeader.tsx
Normal file
17
components/buttonHeader.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { TouchableWithoutFeedback, View } from "react-native";
|
||||||
|
|
||||||
|
type PropsBtnHeader = {
|
||||||
|
onPress?: () => void;
|
||||||
|
item: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ButtonHeader({ onPress, item }: PropsBtnHeader) {
|
||||||
|
return (
|
||||||
|
<TouchableWithoutFeedback onPress={onPress}>
|
||||||
|
<View style={[Styles.btnIconHeader]}>
|
||||||
|
{item}
|
||||||
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
)
|
||||||
|
}
|
||||||
32
components/home/carouselHome.tsx
Normal file
32
components/home/carouselHome.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import React from "react";
|
||||||
|
import { Dimensions, Text, View } from "react-native";
|
||||||
|
import { useSharedValue } from "react-native-reanimated";
|
||||||
|
import Carousel, { ICarouselInstance } from "react-native-reanimated-carousel";
|
||||||
|
|
||||||
|
export default function CaraouselHome() {
|
||||||
|
const ref = React.useRef<ICarouselInstance>(null);
|
||||||
|
const width = Dimensions.get("window").width;
|
||||||
|
const data = [...new Array(6).keys()];
|
||||||
|
const progress = useSharedValue<number>(0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ marginVertical: 20 }}>
|
||||||
|
<Carousel
|
||||||
|
ref={ref}
|
||||||
|
width={width}
|
||||||
|
height={width / 2.5}
|
||||||
|
data={data}
|
||||||
|
loop={true}
|
||||||
|
autoPlay={true}
|
||||||
|
autoPlayInterval={5000}
|
||||||
|
onProgressChange={progress}
|
||||||
|
renderItem={({ index }) => (
|
||||||
|
<View style={Styles.caraoselContent} >
|
||||||
|
<Text style={{ textAlign: "center", color: "white", fontWeight: 'bold' }}>BANNER DARMASABA</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
3
components/home/fiturHome.tsx
Normal file
3
components/home/fiturHome.tsx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default function FiturHome(){
|
||||||
|
|
||||||
|
}
|
||||||
18
components/home/headerRightHome.tsx
Normal file
18
components/home/headerRightHome.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { View } from "react-native"
|
||||||
|
import { router } from "expo-router"
|
||||||
|
import Feather from '@expo/vector-icons/Feather';
|
||||||
|
import { ButtonHeader } from "../buttonHeader";
|
||||||
|
|
||||||
|
export function HeaderRightHome() {
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
width: 140,
|
||||||
|
}}>
|
||||||
|
<ButtonHeader item={<Feather name="search" size={20} color="white" />} onPress={() => { router.push('/') }} />
|
||||||
|
<ButtonHeader item={<Feather name="bell" size={20} color="white" />} onPress={() => { router.push('/') }} />
|
||||||
|
<ButtonHeader item={<Feather name="user" size={20} color="white" />} onPress={() => { router.push('/') }} />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
68
components/inputForm.tsx
Normal file
68
components/inputForm.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { View, TextInput, Text } from "react-native";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
label?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
onChange?: (val: string) => void;
|
||||||
|
info?: string;
|
||||||
|
itemLeft?: React.ReactNode;
|
||||||
|
itemRight?: React.ReactNode;
|
||||||
|
error?: boolean;
|
||||||
|
errorText?: string;
|
||||||
|
required?: boolean;
|
||||||
|
type: 'default' | 'visible-password' | 'numeric'
|
||||||
|
round?: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export function InputForm({ label, placeholder, onChange, info, error, errorText, required, itemLeft, itemRight, type, round }: Props) {
|
||||||
|
|
||||||
|
if (itemLeft != undefined || itemRight != undefined) {
|
||||||
|
return (
|
||||||
|
<View style={{ marginBottom: 10 }}>
|
||||||
|
{
|
||||||
|
label != undefined && (
|
||||||
|
<Text style={[{ marginBottom: 5, textTransform: "capitalize" }, error && Styles.cError]}>
|
||||||
|
{label}
|
||||||
|
{required && (<Text style={Styles.cError}>*</Text>)}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<View style={[Styles.inputRoundForm, itemRight != undefined ? Styles.inputRoundFormRight : Styles.inputRoundFormLeft, round && Styles.round30]}>
|
||||||
|
{itemRight != undefined ? itemRight : itemLeft}
|
||||||
|
<TextInput
|
||||||
|
placeholder={placeholder}
|
||||||
|
keyboardType={type}
|
||||||
|
onChangeText={onChange}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
{error && (<Text style={[Styles.textInformation, Styles.cError]}>{errorText}</Text>)}
|
||||||
|
{info != undefined && (<Text style={[Styles.textInformation, Styles.cGray]}>{info}</Text>)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ marginBottom: 10 }}>
|
||||||
|
{
|
||||||
|
label != undefined && (
|
||||||
|
<Text style={[{ marginBottom: 5, textTransform: "capitalize" }, error && Styles.cError]}>
|
||||||
|
{label}
|
||||||
|
{required && (<Text style={Styles.cError}>*</Text>)}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<TextInput
|
||||||
|
placeholder={placeholder}
|
||||||
|
keyboardType={type}
|
||||||
|
style={[Styles.inputRoundForm, error && { borderColor: "red" }, round && Styles.round30]}
|
||||||
|
onChangeText={onChange}
|
||||||
|
/>
|
||||||
|
{error && (<Text style={[Styles.textInformation, Styles.cError]}>{errorText}</Text>)}
|
||||||
|
{info != undefined && (<Text style={[Styles.textInformation, , Styles.cGray]}>{info}</Text>)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols';
|
|
||||||
import { StyleProp, ViewStyle } from 'react-native';
|
|
||||||
|
|
||||||
export function IconSymbol({
|
|
||||||
name,
|
|
||||||
size = 24,
|
|
||||||
color,
|
|
||||||
style,
|
|
||||||
weight = 'regular',
|
|
||||||
}: {
|
|
||||||
name: SymbolViewProps['name'];
|
|
||||||
size?: number;
|
|
||||||
color: string;
|
|
||||||
style?: StyleProp<ViewStyle>;
|
|
||||||
weight?: SymbolWeight;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<SymbolView
|
|
||||||
weight={weight}
|
|
||||||
tintColor={color}
|
|
||||||
resizeMode="scaleAspectFit"
|
|
||||||
name={name}
|
|
||||||
style={[
|
|
||||||
{
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
},
|
|
||||||
style,
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// This file is a fallback for using MaterialIcons on Android and web.
|
|
||||||
|
|
||||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
||||||
import { SymbolWeight } from 'expo-symbols';
|
|
||||||
import React from 'react';
|
|
||||||
import { OpaqueColorValue, StyleProp, ViewStyle } from 'react-native';
|
|
||||||
|
|
||||||
// Add your SFSymbol to MaterialIcons mappings here.
|
|
||||||
const MAPPING = {
|
|
||||||
// See MaterialIcons here: https://icons.expo.fyi
|
|
||||||
// See SF Symbols in the SF Symbols app on Mac.
|
|
||||||
'house.fill': 'home',
|
|
||||||
'paperplane.fill': 'send',
|
|
||||||
'chevron.left.forwardslash.chevron.right': 'code',
|
|
||||||
'chevron.right': 'chevron-right',
|
|
||||||
} as Partial<
|
|
||||||
Record<
|
|
||||||
import('expo-symbols').SymbolViewProps['name'],
|
|
||||||
React.ComponentProps<typeof MaterialIcons>['name']
|
|
||||||
>
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type IconSymbolName = keyof typeof MAPPING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An icon component that uses native SFSymbols on iOS, and MaterialIcons on Android and web. This ensures a consistent look across platforms, and optimal resource usage.
|
|
||||||
*
|
|
||||||
* Icon `name`s are based on SFSymbols and require manual mapping to MaterialIcons.
|
|
||||||
*/
|
|
||||||
export function IconSymbol({
|
|
||||||
name,
|
|
||||||
size = 24,
|
|
||||||
color,
|
|
||||||
style,
|
|
||||||
}: {
|
|
||||||
name: IconSymbolName;
|
|
||||||
size?: number;
|
|
||||||
color: string | OpaqueColorValue;
|
|
||||||
style?: StyleProp<ViewStyle>;
|
|
||||||
weight?: SymbolWeight;
|
|
||||||
}) {
|
|
||||||
return <MaterialIcons color={color} size={size} name={MAPPING[name]} style={style} />;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
|
|
||||||
import { BlurView } from 'expo-blur';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
||||||
|
|
||||||
export default function BlurTabBarBackground() {
|
|
||||||
return (
|
|
||||||
<BlurView
|
|
||||||
// System chrome material automatically adapts to the system's theme
|
|
||||||
// and matches the native tab bar appearance on iOS.
|
|
||||||
tint="systemChromeMaterial"
|
|
||||||
intensity={100}
|
|
||||||
style={StyleSheet.absoluteFill}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useBottomTabOverflow() {
|
|
||||||
const tabHeight = useBottomTabBarHeight();
|
|
||||||
const { bottom } = useSafeAreaInsets();
|
|
||||||
return tabHeight - bottom;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// This is a shim for web and Android where the tab bar is generally opaque.
|
|
||||||
export default undefined;
|
|
||||||
|
|
||||||
export function useBottomTabOverflow() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -3,13 +3,13 @@
|
|||||||
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
|
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const tintColorLight = '#0a7ea4';
|
const tintColorLight = '#19345E';
|
||||||
const tintColorDark = '#fff';
|
const tintColorDark = '#fff';
|
||||||
|
|
||||||
export const Colors = {
|
export const Colors = {
|
||||||
light: {
|
light: {
|
||||||
text: '#11181C',
|
text: '#11181C',
|
||||||
background: '#fff',
|
background: '#f4f9fd',
|
||||||
tint: tintColorLight,
|
tint: tintColorLight,
|
||||||
icon: '#687076',
|
icon: '#687076',
|
||||||
tabIconDefault: '#687076',
|
tabIconDefault: '#687076',
|
||||||
|
|||||||
18
constants/Headers.ts
Normal file
18
constants/Headers.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const bgColorDefault = '#19345E';
|
||||||
|
|
||||||
|
export const Headers = {
|
||||||
|
shadow: {
|
||||||
|
headerStyle: {
|
||||||
|
backgroundColor: bgColorDefault,
|
||||||
|
},
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
headerShadowVisible: true
|
||||||
|
},
|
||||||
|
noShadow: {
|
||||||
|
headerStyle: {
|
||||||
|
backgroundColor: bgColorDefault,
|
||||||
|
},
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
headerShadowVisible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
124
constants/Styles.ts
Normal file
124
constants/Styles.ts
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import { StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
const Styles = StyleSheet.create({
|
||||||
|
wrapLogin: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
alignItems: "stretch",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
textDefault: {
|
||||||
|
fontSize: 16,
|
||||||
|
lineHeight: 24,
|
||||||
|
},
|
||||||
|
textDefaultSemiBold: {
|
||||||
|
fontSize: 16,
|
||||||
|
lineHeight: 24,
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
textMediumNormal: {
|
||||||
|
fontSize: 13,
|
||||||
|
lineHeight: 24,
|
||||||
|
},
|
||||||
|
textMediumSemiBold: {
|
||||||
|
fontSize: 13,
|
||||||
|
lineHeight: 24,
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
textTitle: {
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
lineHeight: 32,
|
||||||
|
},
|
||||||
|
textSubtitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
textLink: {
|
||||||
|
lineHeight: 30,
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#0a7ea4',
|
||||||
|
},
|
||||||
|
textInformation: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'light',
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
cError: {
|
||||||
|
color: '#DB1514'
|
||||||
|
},
|
||||||
|
cGray: {
|
||||||
|
color: 'gray'
|
||||||
|
},
|
||||||
|
cWhite: {
|
||||||
|
color: 'white'
|
||||||
|
},
|
||||||
|
cDefault: {
|
||||||
|
color: '#19345E'
|
||||||
|
},
|
||||||
|
mb15: {
|
||||||
|
marginBottom: 15
|
||||||
|
},
|
||||||
|
mb30: {
|
||||||
|
marginBottom: 30
|
||||||
|
},
|
||||||
|
round30: {
|
||||||
|
borderRadius: 30
|
||||||
|
},
|
||||||
|
btnIconHeader: {
|
||||||
|
backgroundColor: '#384288',
|
||||||
|
padding: 7,
|
||||||
|
borderRadius: 100,
|
||||||
|
},
|
||||||
|
btnRound: {
|
||||||
|
backgroundColor: '#19345E',
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: '#19345E',
|
||||||
|
alignItems: 'center',
|
||||||
|
borderRadius: 30,
|
||||||
|
marginTop: 15,
|
||||||
|
paddingVertical: 10
|
||||||
|
},
|
||||||
|
inputRoundForm: {
|
||||||
|
borderRadius: 10,
|
||||||
|
borderColor: '#19345E',
|
||||||
|
borderWidth: 1,
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
},
|
||||||
|
inputRoundFormLeft: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: 0,
|
||||||
|
},
|
||||||
|
inputRoundFormRight: {
|
||||||
|
flexDirection: 'row-reverse',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: 0,
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
},
|
||||||
|
verificationCell: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
lineHeight: 45,
|
||||||
|
fontSize: 24,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 15,
|
||||||
|
borderColor: 'gray',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
verificationFocusCell: {
|
||||||
|
borderColor: '#19345E',
|
||||||
|
},
|
||||||
|
caraoselContent: {
|
||||||
|
flex: 1,
|
||||||
|
borderWidth: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
marginHorizontal: 15,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: '#19345E',
|
||||||
|
display: 'flex',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default Styles;
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { useColorScheme } from 'react-native';
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useColorScheme as useRNColorScheme } from 'react-native';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To support static rendering, this value needs to be re-calculated on the client side for web
|
|
||||||
*/
|
|
||||||
export function useColorScheme() {
|
|
||||||
const [hasHydrated, setHasHydrated] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setHasHydrated(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const colorScheme = useRNColorScheme();
|
|
||||||
|
|
||||||
if (hasHydrated) {
|
|
||||||
return colorScheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'light';
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Learn more about light and dark modes:
|
|
||||||
* https://docs.expo.dev/guides/color-schemes/
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Colors } from '@/constants/Colors';
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
export function useThemeColor(
|
|
||||||
props: { light?: string; dark?: string },
|
|
||||||
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
|
||||||
) {
|
|
||||||
const theme = useColorScheme() ?? 'light';
|
|
||||||
const colorFromProps = props[theme];
|
|
||||||
|
|
||||||
if (colorFromProps) {
|
|
||||||
return colorFromProps;
|
|
||||||
} else {
|
|
||||||
return Colors[theme][colorName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,8 +33,10 @@
|
|||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"react-native": "0.76.7",
|
"react-native": "0.76.7",
|
||||||
|
"react-native-confirmation-code-field": "^7.4.0",
|
||||||
"react-native-gesture-handler": "~2.20.2",
|
"react-native-gesture-handler": "~2.20.2",
|
||||||
"react-native-reanimated": "~3.16.1",
|
"react-native-reanimated": "~3.16.1",
|
||||||
|
"react-native-reanimated-carousel": "^4.0.2",
|
||||||
"react-native-safe-area-context": "4.12.0",
|
"react-native-safe-area-context": "4.12.0",
|
||||||
"react-native-screens": "~4.4.0",
|
"react-native-screens": "~4.4.0",
|
||||||
"react-native-web": "~0.19.13",
|
"react-native-web": "~0.19.13",
|
||||||
|
|||||||
Reference in New Issue
Block a user