Add Dialog Choose Payment Method to implement payment method feature. Then, add Billing Code and Other Method screens, followed by their several UI components
This commit is contained in:
@ -6,10 +6,15 @@ import FontFamily from '../../assets/styles/FontFamily';
|
||||
|
||||
type AccordionProps = {
|
||||
title: string;
|
||||
titleRegular?: boolean;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const Accordion: React.FC<AccordionProps> = ({title, children}) => {
|
||||
const Accordion: React.FC<AccordionProps> = ({
|
||||
title,
|
||||
titleRegular = false,
|
||||
children,
|
||||
}) => {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
||||
return (
|
||||
@ -22,7 +27,14 @@ const Accordion: React.FC<AccordionProps> = ({title, children}) => {
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
onPress={() => setExpanded(!expanded)}>
|
||||
<Text style={styles.accordionTitle}>{title}</Text>
|
||||
<Text
|
||||
style={
|
||||
titleRegular
|
||||
? styles.accordionTitleRegular
|
||||
: styles.accordionTitleBold
|
||||
}>
|
||||
{title}
|
||||
</Text>
|
||||
<Icon
|
||||
name={expanded ? 'chevron-up' : 'chevron-down'}
|
||||
size={24}
|
||||
@ -35,12 +47,18 @@ const Accordion: React.FC<AccordionProps> = ({title, children}) => {
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
accordionTitle: {
|
||||
accordionTitleBold: {
|
||||
...FontFamily.notoSansBold,
|
||||
includeFontPadding: false,
|
||||
fontSize: 14,
|
||||
color: Colors.secondary30.color,
|
||||
},
|
||||
accordionTitleRegular: {
|
||||
...FontFamily.notoSansRegular,
|
||||
includeFontPadding: false,
|
||||
fontSize: 14,
|
||||
color: Colors.secondary30.color,
|
||||
},
|
||||
});
|
||||
|
||||
export default Accordion;
|
||||
|
91
src/components/dialog/DialogChoosePaymentMethod.tsx
Normal file
91
src/components/dialog/DialogChoosePaymentMethod.tsx
Normal file
@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
import {View, Text, StyleSheet, Pressable} from 'react-native';
|
||||
import {Portal, Dialog} from 'react-native-paper';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
import ReceiptTextCheckOutlineIcon from '../../../assets/icons/receipt_text_check_outline.svg';
|
||||
|
||||
type Props = {
|
||||
visible: boolean;
|
||||
onBillingCodePress: () => void;
|
||||
onOtherMethodPress: () => void;
|
||||
};
|
||||
|
||||
const DialogChoosePaymentMethod = (props: Props) => {
|
||||
const {visible, onBillingCodePress, onOtherMethodPress} = props;
|
||||
return (
|
||||
<Portal>
|
||||
<Dialog visible={visible} style={styles.dialogContainer}>
|
||||
<Dialog.Title style={styles.dialogTitle}>
|
||||
Pilih metode pembayaran
|
||||
</Dialog.Title>
|
||||
<View style={styles.dialogContentContainer}>
|
||||
<Pressable
|
||||
onPress={onBillingCodePress}
|
||||
style={({pressed}) => [
|
||||
styles.dialogButtonContainer,
|
||||
{
|
||||
transform: [{scale: pressed ? 0.975 : 1}],
|
||||
},
|
||||
]}>
|
||||
<Icon
|
||||
name="credit-card-settings-outline"
|
||||
color={Colors.neutral100.color}
|
||||
size={24}
|
||||
/>
|
||||
<Text style={styles.dialogTextButton}>Kode Biling</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={onOtherMethodPress}
|
||||
style={({pressed}) => [
|
||||
styles.dialogButtonContainer,
|
||||
{
|
||||
transform: [{scale: pressed ? 0.975 : 1}],
|
||||
},
|
||||
]}>
|
||||
<ReceiptTextCheckOutlineIcon />
|
||||
<Text style={styles.dialogTextButton}>Metode Lain</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
dialogContainer: {
|
||||
backgroundColor: 'white',
|
||||
elevation: 0,
|
||||
shadowColor: 'transparent',
|
||||
borderRadius: 20,
|
||||
},
|
||||
dialogTitle: {
|
||||
fontSize: 22,
|
||||
color: Colors.secondary30.color,
|
||||
},
|
||||
dialogContentContainer: {
|
||||
marginHorizontal: 24,
|
||||
marginBottom: 24,
|
||||
gap: 32,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
dialogButtonContainer: {
|
||||
backgroundColor: Colors.primary30.color,
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
gap: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
dialogTextButton: {
|
||||
width: 75,
|
||||
...FontFamily.notoSansMedium,
|
||||
fontSize: 14,
|
||||
color: Colors.neutral100.color,
|
||||
includeFontPadding: false,
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default DialogChoosePaymentMethod;
|
@ -20,6 +20,8 @@ import ApplicationDetailScreen from '../screens/applicationDetail';
|
||||
import PassportRequirementsScreen from '../screens/passportRequirements';
|
||||
import ApplicationGuideScreen from '../screens/applicationGuide';
|
||||
import SeeRequirementsScreen from '../screens/seeRequirements';
|
||||
import OtherMethodScreen from '../screens/otherMethod';
|
||||
import BillingCodeScreen from '../screens/billingCode';
|
||||
|
||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
||||
|
||||
@ -52,7 +54,7 @@ function RootStack() {
|
||||
options={{headerShown: false}}
|
||||
/>
|
||||
<Stack.Screen name="Home" options={{headerShown: false}}>
|
||||
{() => <HomeScreen showDialog={() => console.log('Show dialog!')} />}
|
||||
{() => <HomeScreen showDialog={() => console.log('Show dialog!')} visible />}
|
||||
</Stack.Screen>
|
||||
<Stack.Screen
|
||||
name="History"
|
||||
@ -119,6 +121,16 @@ function RootStack() {
|
||||
component={SeeRequirementsScreen}
|
||||
options={{headerShown: false}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="BillingCode"
|
||||
component={BillingCodeScreen}
|
||||
options={{headerShown: false}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="OtherMethod"
|
||||
component={OtherMethodScreen}
|
||||
options={{headerShown: false}}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
||||
|
@ -20,4 +20,6 @@ export type RootStackParamList = {
|
||||
ApplicationGuide: undefined;
|
||||
PassportRequirements: undefined;
|
||||
SeeRequirements: undefined;
|
||||
OtherMethod: undefined;
|
||||
BillingCode: undefined;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import {ScrollView, StatusBar, Text, View} from 'react-native';
|
||||
import styles from './styles';
|
||||
import {useNavigation, useRoute} from '@react-navigation/native';
|
||||
@ -7,18 +7,90 @@ import Colors from '../../../assets/styles/Colors';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {Button, Divider} from 'react-native-paper';
|
||||
import {Button, Divider, PaperProvider} from 'react-native-paper';
|
||||
import DialogChoosePaymentMethod from '../../components/dialog/DialogChoosePaymentMethod';
|
||||
|
||||
type ApplicationDetailScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'ApplicationDetail'
|
||||
>;
|
||||
|
||||
const renderApplicantDetailContent = () => {
|
||||
const RenderStatusSection = (showDialog: () => void) => {
|
||||
const route = useRoute();
|
||||
const {data} = route.params as {data: PassportAppointmentData};
|
||||
const navigation = useNavigation<ApplicationDetailScreenNavigationProp>();
|
||||
|
||||
if (data.status === 'Sudah Terbayar') {
|
||||
return (
|
||||
<>
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<View style={styles.applicantDetailFeeContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
<Icon
|
||||
name="check-circle"
|
||||
size={18}
|
||||
color={Colors.indicatorGreen.color}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Button
|
||||
mode="contained"
|
||||
style={styles.applicantDetailContentChildButton}
|
||||
onPress={() => {}}
|
||||
textColor={Colors.neutral100.color}>
|
||||
Download Surat Pengantar Menuju KANIM
|
||||
</Button>
|
||||
<Button
|
||||
mode="outlined"
|
||||
textColor={Colors.primary30.color}
|
||||
style={styles.applicantDetailContentChildButtonOutlined}
|
||||
onPress={() => navigation.navigate('SeeRequirements')}>
|
||||
Lihat Persyaratan
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (data.status === 'Permohonan Kadaluarsa') {
|
||||
return (
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<View style={styles.applicantDetailFeeContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
<Icon name="clock" size={18} color={Colors.indicatorOrange.color} />
|
||||
</View>
|
||||
</View>
|
||||
<Button
|
||||
mode="contained"
|
||||
style={styles.applicantDetailContentChildButton}
|
||||
onPress={showDialog}
|
||||
textColor={Colors.neutral100.color}>
|
||||
Lanjut Pembayaran
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const RenderApplicantDetailContent = (showDialog: () => void) => {
|
||||
const route = useRoute();
|
||||
const {data} = route.params as {data: PassportAppointmentData};
|
||||
|
||||
return (
|
||||
<View style={styles.applicantDetailContentContainer}>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
@ -26,14 +98,18 @@ const renderApplicantDetailContent = () => {
|
||||
<Text
|
||||
style={[
|
||||
styles.applicantDetailTextDesc,
|
||||
{textTransform: 'uppercase', textAlign: 'right'},
|
||||
styles.applicantDetailTexDescName,
|
||||
]}>
|
||||
{data.applicantName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
<Text style={styles.applicantDetailTextTitle}>Kode Permohonan</Text>
|
||||
<Text style={[styles.applicantDetailTextDesc, {textAlign: 'right'}]}>
|
||||
<Text
|
||||
style={[
|
||||
styles.applicantDetailTextDesc,
|
||||
styles.applicantDetailTexDescCode,
|
||||
]}>
|
||||
{data.applicantCode}
|
||||
</Text>
|
||||
</View>
|
||||
@ -78,65 +154,7 @@ const renderApplicantDetailContent = () => {
|
||||
</View>
|
||||
</View>
|
||||
<Divider />
|
||||
{data.status === 'Sudah Terbayar' ? (
|
||||
<>
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<View style={styles.applicantDetailFeeContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
<Icon
|
||||
name="check-circle"
|
||||
size={18}
|
||||
color={Colors.indicatorGreen.color}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Button
|
||||
mode="contained"
|
||||
style={styles.applicantDetailContentChildButton}
|
||||
onPress={() => {}}>
|
||||
Download Surat Pengantar Menuju KANIM
|
||||
</Button>
|
||||
<Button
|
||||
mode="outlined"
|
||||
textColor={Colors.primary30.color}
|
||||
style={styles.applicantDetailContentChildButtonOutlined}
|
||||
onPress={() => navigation.navigate('SeeRequirements')}>
|
||||
Lihat Persyaratan
|
||||
</Button>
|
||||
</>
|
||||
) : data.status === 'Permohonan Kadaluarsa' ? (
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<View style={styles.applicantDetailFeeContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{data.applicationDetails.fee}
|
||||
</Text>
|
||||
<Icon
|
||||
name="clock"
|
||||
size={18}
|
||||
color={Colors.indicatorOrange.color}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Button
|
||||
mode="contained"
|
||||
style={styles.applicantDetailContentChildButton}
|
||||
onPress={() => {}}>
|
||||
Lanjut Pembayaran
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{RenderStatusSection(showDialog)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@ -199,77 +217,101 @@ function ApplicationDetailScreen() {
|
||||
|
||||
const navigation = useNavigation<ApplicationDetailScreenNavigationProp>();
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const showDialog = () => setVisible(true);
|
||||
const hideDialog = () => setVisible(false);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.secondary30.color}
|
||||
barStyle="light-content"
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarIcon}
|
||||
color={Colors.neutral100.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
<PaperProvider>
|
||||
<StatusBar
|
||||
backgroundColor={visible ? '#295e70' : Colors.secondary30.color}
|
||||
barStyle="light-content"
|
||||
/>
|
||||
<Text style={styles.appBarTitle}>Detail Permohonan</Text>
|
||||
</View>
|
||||
<ScrollView>
|
||||
<View style={styles.topContainer} />
|
||||
<View style={styles.statusContentContainer}>
|
||||
{renderStatusContent(data.status)}
|
||||
<View style={styles.appBarContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarIcon}
|
||||
color={Colors.neutral100.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<Text style={styles.appBarTitle}>Detail Permohonan</Text>
|
||||
</View>
|
||||
<View style={styles.midContainer}>
|
||||
<Text style={styles.midTextTitle}>Jadwal Kedatangan</Text>
|
||||
<View style={styles.midIconContainer}>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="calendar-today"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.appointmentDate}
|
||||
</Text>
|
||||
<ScrollView>
|
||||
<View style={styles.topContainer} />
|
||||
<View style={styles.statusContentContainer}>
|
||||
{renderStatusContent(data.status)}
|
||||
</View>
|
||||
<View style={styles.midContainer}>
|
||||
<Text style={styles.midTextTitle}>Jadwal Kedatangan</Text>
|
||||
<View style={styles.midIconContainer}>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="calendar-today"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.appointmentDate}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="clock-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.appointmentTime}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="map-marker-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.serviceUnit}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="clock-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.appointmentTime}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
<Icon
|
||||
name="map-marker-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{data.serviceUnit}
|
||||
</Text>
|
||||
<Divider />
|
||||
<View style={styles.midTextContentContainer}>
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>
|
||||
Tanggal Pengajuan
|
||||
</Text>
|
||||
<Text style={styles.midTextContentData}>
|
||||
{data.submissionDate}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>Kode Layanan</Text>
|
||||
<Text style={styles.midTextContentData}>
|
||||
{data.serviceCode}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<Divider />
|
||||
<View style={styles.midTextContentContainer}>
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>Tanggal Pengajuan</Text>
|
||||
<Text style={styles.midTextContentData}>
|
||||
{data.submissionDate}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>Kode Layanan</Text>
|
||||
<Text style={styles.midTextContentData}>{data.serviceCode}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View>{renderApplicantDetailContent()}</View>
|
||||
</ScrollView>
|
||||
<View>{RenderApplicantDetailContent(showDialog)}</View>
|
||||
</ScrollView>
|
||||
{visible && (
|
||||
<DialogChoosePaymentMethod
|
||||
visible={visible}
|
||||
onBillingCodePress={() => {
|
||||
navigation.navigate('BillingCode');
|
||||
hideDialog();
|
||||
}}
|
||||
onOtherMethodPress={() => {
|
||||
navigation.navigate('OtherMethod');
|
||||
hideDialog();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</PaperProvider>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -126,6 +126,13 @@ const styles = StyleSheet.create({
|
||||
color: Colors.primary30.color,
|
||||
flex: 1.2,
|
||||
},
|
||||
applicantDetailTexDescName: {
|
||||
textTransform: 'uppercase',
|
||||
textAlign: 'right',
|
||||
},
|
||||
applicantDetailTexDescCode: {
|
||||
textAlign: 'right',
|
||||
},
|
||||
applicantDetailContentChildContainer: {
|
||||
padding: 16,
|
||||
borderWidth: 1,
|
||||
|
146
src/screens/billingCode/index.tsx
Normal file
146
src/screens/billingCode/index.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import {ScrollView, StatusBar, View} from 'react-native';
|
||||
import {Divider, Text} from 'react-native-paper';
|
||||
import styles from './styles';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import Accordion from '../../components/Accordion';
|
||||
|
||||
type BillingCodeScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'BillingCode'
|
||||
>;
|
||||
|
||||
function BillingCodeScreen() {
|
||||
const navigation = useNavigation<BillingCodeScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.neutral100.color}
|
||||
barStyle="dark-content"
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarIcon}
|
||||
color={Colors.secondary30.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<Text style={styles.appBarTitle}>Kode Billing</Text>
|
||||
</View>
|
||||
<ScrollView>
|
||||
<View style={styles.billingCodeCardContainer}>
|
||||
<View style={styles.billingCodeContentWrapper}>
|
||||
<Text style={styles.billingCodeTextTitle}>Kode Billing</Text>
|
||||
<View style={styles.billingCodeIconContentWrapper}>
|
||||
<Text style={styles.billingCodeTextNumber}>12345678901234</Text>
|
||||
<Icon
|
||||
name="content-copy"
|
||||
size={16}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Divider style={styles.divider} />
|
||||
<View style={styles.billingCodeContentWrapper}>
|
||||
<View style={styles.billingCodeIconContentWrapper}>
|
||||
<Icon name="tray-arrow-down" size={18} />
|
||||
<Text style={styles.billingCodeTextDesc}>
|
||||
Unduh PDF Kode Billing Pembayaran Paspor
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.billingCodeDataContentContainer}>
|
||||
<Text style={styles.paymentMethodTitle}>Cara Pembayaran</Text>
|
||||
<View style={styles.paymentMethodContainer}>
|
||||
<View style={styles.paymentMethodOptionTitleWrapper}>
|
||||
<Text style={styles.paymentMethodOptionTitle}>1.</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.paymentMethodOptionTitle,
|
||||
styles.paymentMethodOptionTitleFlex,
|
||||
]}>
|
||||
ATM
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.paymentMethodOptionAccordionContainer}>
|
||||
<Accordion title="BCA" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BNI" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BRI" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="Mandiri" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.paymentMethodContainer}>
|
||||
<View style={styles.paymentMethodOptionTitleWrapper}>
|
||||
<Text style={styles.paymentMethodOptionTitle}>2.</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.paymentMethodOptionTitle,
|
||||
styles.paymentMethodOptionTitleFlex,
|
||||
]}>
|
||||
Mobile Banking dan Internet Banking
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.paymentMethodOptionAccordionContainer}>
|
||||
<Accordion title="BNI (Mobile Banking)" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BCA (Internet Banking)" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BRI (Internet Banking)" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BRImo (Mobile Banking)" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
title="Livin’ by Mandiri (Mobile Banking)"
|
||||
titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
<Accordion title="BSI Mobile (Mobile Banking)" titleRegular>
|
||||
<View>
|
||||
<Text>Content</Text>
|
||||
</View>
|
||||
</Accordion>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default BillingCodeScreen;
|
97
src/screens/billingCode/styles.tsx
Normal file
97
src/screens/billingCode/styles.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
},
|
||||
appBarTitle: {
|
||||
color: Colors.secondary30.color,
|
||||
...FontFamily.notoSansRegular,
|
||||
fontSize: 20,
|
||||
marginStart: 16,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
appBarIcon: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
appBarContainer: {
|
||||
height: 64,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
},
|
||||
billingCodeCardContainer: {
|
||||
marginTop: 4,
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.secondary70.color,
|
||||
borderRadius: 8,
|
||||
},
|
||||
billingCodeIconContentWrapper: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
alignItems: 'center',
|
||||
},
|
||||
divider: {
|
||||
backgroundColor: Colors.secondary70.color,
|
||||
height: 1,
|
||||
},
|
||||
billingCodeContentWrapper: {
|
||||
padding: 16,
|
||||
gap: 8,
|
||||
},
|
||||
billingCodeTextTitle: {
|
||||
...FontFamily.notoSansMedium,
|
||||
fontSize: 12,
|
||||
includeFontPadding: false,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
billingCodeTextNumber: {
|
||||
...FontFamily.notoSansExtraBold,
|
||||
fontSize: 16,
|
||||
includeFontPadding: false,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
billingCodeTextDesc: {
|
||||
...FontFamily.notoSansMedium,
|
||||
fontSize: 12,
|
||||
includeFontPadding: false,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
billingCodeDataContentContainer: {
|
||||
marginHorizontal: 16,
|
||||
gap: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
paymentMethodContainer: {
|
||||
gap: 12,
|
||||
},
|
||||
paymentMethodTitle: {
|
||||
includeFontPadding: false,
|
||||
fontSize: 18,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
paymentMethodOptionTitleWrapper: {
|
||||
gap: 6,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
paymentMethodOptionTitle: {
|
||||
color: Colors.primary30.color,
|
||||
includeFontPadding: false,
|
||||
fontSize: 16,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
},
|
||||
paymentMethodOptionTitleFlex: {
|
||||
flex: 1,
|
||||
},
|
||||
paymentMethodOptionAccordionContainer: {
|
||||
marginStart: 24,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
@ -37,7 +37,7 @@ function CloseAccountScreen() {
|
||||
<PaperProvider>
|
||||
<View style={styles.contentContainer}>
|
||||
<StatusBar
|
||||
backgroundColor={visible ? Colors.primary30.color : Colors.primary30.color}
|
||||
backgroundColor={visible ? '#ADADAF' : Colors.neutral100.color}
|
||||
barStyle={visible ? 'light-content' : 'dark-content'}
|
||||
/>
|
||||
<View>
|
||||
|
@ -14,14 +14,14 @@ import Colors from '../../../assets/styles/Colors';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import {useFocusEffect, useNavigation} from '@react-navigation/native';
|
||||
import RegularPassportIcon from '../../../assets/icons/regular_passport.svg';
|
||||
import ExpressPassportIcon from '../../../assets/icons/express_passport.svg';
|
||||
import GuidebookIcon from '../../../assets/icons/guidebook.svg';
|
||||
import EazyPassportIcon from '../../../assets/icons/eazy_passport.svg';
|
||||
import passportAppointmentData from '../../data/History/PassportAppointmentData';
|
||||
import PassportAppointmentCard from '../../components/PassportAppointmentCard';
|
||||
import {useRef} from 'react';
|
||||
import {useCallback, useRef} from 'react';
|
||||
|
||||
type HomeScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
@ -59,7 +59,7 @@ const RenderBanner = () => {
|
||||
<>
|
||||
<Animated.FlatList
|
||||
data={data}
|
||||
keyExtractor={item => item.toString()}
|
||||
keyExtractor={item => item.id.toString()}
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
snapToInterval={ITEM_WIDTH}
|
||||
@ -253,15 +253,25 @@ const RenderContent = ({showDialog}: RenderContentProps) => {
|
||||
|
||||
type HomeScreenProps = {
|
||||
readonly showDialog: () => void;
|
||||
readonly visible: boolean;
|
||||
};
|
||||
|
||||
function HomeScreen({showDialog}: HomeScreenProps) {
|
||||
function HomeScreen({showDialog, visible}: HomeScreenProps) {
|
||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
StatusBar.setBackgroundColor(
|
||||
visible ? '#295E70' : Colors.secondary30.color,
|
||||
);
|
||||
StatusBar.setBarStyle('light-content');
|
||||
}, [visible]),
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.secondary30.color}
|
||||
backgroundColor={visible ? '#295E70' : Colors.secondary30.color}
|
||||
barStyle={'light-content'}
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
|
@ -12,7 +12,7 @@ import ProfileScreen from '../profile';
|
||||
import styles from './styles';
|
||||
import HomeScreen from '../home';
|
||||
import HistoryScreen from '../history';
|
||||
import {StatusBar, View} from 'react-native';
|
||||
import {View} from 'react-native';
|
||||
import {useState} from 'react';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
@ -54,7 +54,7 @@ function NavigationRouteScreen() {
|
||||
const renderScene = ({route}: {route: {key: string}}) => {
|
||||
switch (route.key) {
|
||||
case 'home':
|
||||
return <HomeScreen showDialog={showDialog} />;
|
||||
return <HomeScreen showDialog={showDialog} visible={visible} />;
|
||||
case 'history':
|
||||
return <HistoryScreen />;
|
||||
case 'profile':
|
||||
|
37
src/screens/otherMethod/index.tsx
Normal file
37
src/screens/otherMethod/index.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import {StatusBar, View} from 'react-native';
|
||||
import {Text} from 'react-native-paper';
|
||||
import styles from './styles';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
|
||||
type OtherMethodScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'OtherMethod'
|
||||
>;
|
||||
|
||||
function OtherMethodScreen() {
|
||||
const navigation = useNavigation<OtherMethodScreenNavigationProp>();
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.neutral100.color}
|
||||
barStyle="dark-content"
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarIcon}
|
||||
color={Colors.secondary30.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<Text style={styles.appBarTitle}>Metode Lain</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default OtherMethodScreen;
|
28
src/screens/otherMethod/styles.tsx
Normal file
28
src/screens/otherMethod/styles.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
},
|
||||
appBarTitle: {
|
||||
color: Colors.secondary30.color,
|
||||
...FontFamily.notoSansRegular,
|
||||
fontSize: 20,
|
||||
marginStart: 16,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
appBarIcon: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
appBarContainer: {
|
||||
height: 64,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
Reference in New Issue
Block a user