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:
3
assets/icons/receipt_text_check_outline.svg
Normal file
3
assets/icons/receipt_text_check_outline.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.76 20.74L12.5 22L11 20.5L9.5 22L8 20.5L6.5 22L5 20.5L3.5 22V2L5 3.5L6.5 2L8 3.5L9.5 2L11 3.5L12.5 2L14 3.5L15.5 2L17 3.5L18.5 2L20 3.5L21.5 2V13.35C20.87 13.13 20.2 13 19.5 13V5H5.5V19H13.5C13.5 19.57 13.6 20.22 13.76 20.74ZM6.5 15V17H13.85C14.11 16.25 14.5 15.58 15.04 15H6.5ZM6.5 13H18.5V11H6.5V13ZM6.5 9H18.5V7H6.5V9ZM23.5 17.23L22.34 15.82L18.75 19.41L17.16 17.82L16 19L18.75 22" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 515 B |
@ -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