diff --git a/assets/icons/receipt_text_check_outline.svg b/assets/icons/receipt_text_check_outline.svg
new file mode 100644
index 0000000..4ad8cca
--- /dev/null
+++ b/assets/icons/receipt_text_check_outline.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/components/Accordion.tsx b/src/components/Accordion.tsx
index f68c9a5..510f8d9 100644
--- a/src/components/Accordion.tsx
+++ b/src/components/Accordion.tsx
@@ -6,10 +6,15 @@ import FontFamily from '../../assets/styles/FontFamily';
type AccordionProps = {
title: string;
+ titleRegular?: boolean;
children: ReactNode;
};
-const Accordion: React.FC = ({title, children}) => {
+const Accordion: React.FC = ({
+ title,
+ titleRegular = false,
+ children,
+}) => {
const [expanded, setExpanded] = useState(false);
return (
@@ -22,7 +27,14 @@ const Accordion: React.FC = ({title, children}) => {
justifyContent: 'space-between',
})}
onPress={() => setExpanded(!expanded)}>
- {title}
+
+ {title}
+
= ({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;
diff --git a/src/components/dialog/DialogChoosePaymentMethod.tsx b/src/components/dialog/DialogChoosePaymentMethod.tsx
new file mode 100644
index 0000000..ed7a0f4
--- /dev/null
+++ b/src/components/dialog/DialogChoosePaymentMethod.tsx
@@ -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 (
+
+
+
+ );
+};
+
+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;
diff --git a/src/navigation/RootStack.tsx b/src/navigation/RootStack.tsx
index 0068ea8..6d9c660 100644
--- a/src/navigation/RootStack.tsx
+++ b/src/navigation/RootStack.tsx
@@ -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();
@@ -52,7 +54,7 @@ function RootStack() {
options={{headerShown: false}}
/>
- {() => console.log('Show dialog!')} />}
+ {() => console.log('Show dialog!')} visible />}
+
+
);
}
diff --git a/src/navigation/type.ts b/src/navigation/type.ts
index 1cee857..4627747 100644
--- a/src/navigation/type.ts
+++ b/src/navigation/type.ts
@@ -20,4 +20,6 @@ export type RootStackParamList = {
ApplicationGuide: undefined;
PassportRequirements: undefined;
SeeRequirements: undefined;
+ OtherMethod: undefined;
+ BillingCode: undefined;
};
diff --git a/src/screens/applicationDetail/index.tsx b/src/screens/applicationDetail/index.tsx
index 107eca3..2eebe06 100644
--- a/src/screens/applicationDetail/index.tsx
+++ b/src/screens/applicationDetail/index.tsx
@@ -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();
+ if (data.status === 'Sudah Terbayar') {
+ return (
+ <>
+
+ Biaya
+
+
+ {data.applicationDetails.fee}
+
+
+
+
+
+
+ >
+ );
+ }
+
+ if (data.status === 'Permohonan Kadaluarsa') {
+ return (
+
+ Biaya
+
+ {data.applicationDetails.fee}
+
+
+ );
+ }
+
+ return (
+ <>
+
+ Biaya
+
+
+ {data.applicationDetails.fee}
+
+
+
+
+
+ >
+ );
+};
+
+const RenderApplicantDetailContent = (showDialog: () => void) => {
+ const route = useRoute();
+ const {data} = route.params as {data: PassportAppointmentData};
+
return (
@@ -26,14 +98,18 @@ const renderApplicantDetailContent = () => {
{data.applicantName}
Kode Permohonan
-
+
{data.applicantCode}
@@ -78,65 +154,7 @@ const renderApplicantDetailContent = () => {
- {data.status === 'Sudah Terbayar' ? (
- <>
-
- Biaya
-
-
- {data.applicationDetails.fee}
-
-
-
-
-
-
- >
- ) : data.status === 'Permohonan Kadaluarsa' ? (
-
- Biaya
-
- {data.applicationDetails.fee}
-
-
- ) : (
- <>
-
- Biaya
-
-
- {data.applicationDetails.fee}
-
-
-
-
-
- >
- )}
+ {RenderStatusSection(showDialog)}
);
};
@@ -199,77 +217,101 @@ function ApplicationDetailScreen() {
const navigation = useNavigation();
+ const [visible, setVisible] = useState(false);
+
+ const showDialog = () => setVisible(true);
+ const hideDialog = () => setVisible(false);
+
return (
-
-
- navigation.goBack()}
+
+
- Detail Permohonan
-
-
-
-
- {renderStatusContent(data.status)}
+
+ navigation.goBack()}
+ />
+ Detail Permohonan
-
- Jadwal Kedatangan
-
-
-
-
- {data.appointmentDate}
-
+
+
+
+ {renderStatusContent(data.status)}
+
+
+ Jadwal Kedatangan
+
+
+
+
+ {data.appointmentDate}
+
+
+
+
+
+ {data.appointmentTime}
+
+
+
+
+
+ {data.serviceUnit}
+
+
-
-
-
- {data.appointmentTime}
-
-
-
-
-
- {data.serviceUnit}
-
+
+
+
+
+ Tanggal Pengajuan
+
+
+ {data.submissionDate}
+
+
+
+ Kode Layanan
+
+ {data.serviceCode}
+
+
-
-
-
- Tanggal Pengajuan
-
- {data.submissionDate}
-
-
-
- Kode Layanan
- {data.serviceCode}
-
-
-
- {renderApplicantDetailContent()}
-
+ {RenderApplicantDetailContent(showDialog)}
+
+ {visible && (
+ {
+ navigation.navigate('BillingCode');
+ hideDialog();
+ }}
+ onOtherMethodPress={() => {
+ navigation.navigate('OtherMethod');
+ hideDialog();
+ }}
+ />
+ )}
+
);
}
diff --git a/src/screens/applicationDetail/styles.tsx b/src/screens/applicationDetail/styles.tsx
index 1761815..d5c529f 100644
--- a/src/screens/applicationDetail/styles.tsx
+++ b/src/screens/applicationDetail/styles.tsx
@@ -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,
diff --git a/src/screens/billingCode/index.tsx b/src/screens/billingCode/index.tsx
new file mode 100644
index 0000000..ae4f760
--- /dev/null
+++ b/src/screens/billingCode/index.tsx
@@ -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();
+
+ return (
+
+
+
+ navigation.goBack()}
+ />
+ Kode Billing
+
+
+
+
+ Kode Billing
+
+ 12345678901234
+
+
+
+
+
+
+
+
+ Unduh PDF Kode Billing Pembayaran Paspor
+
+
+
+
+
+ Cara Pembayaran
+
+
+ 1.
+
+ ATM
+
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+
+
+ 2.
+
+ Mobile Banking dan Internet Banking
+
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+
+
+
+ );
+}
+
+export default BillingCodeScreen;
diff --git a/src/screens/billingCode/styles.tsx b/src/screens/billingCode/styles.tsx
new file mode 100644
index 0000000..6a31241
--- /dev/null
+++ b/src/screens/billingCode/styles.tsx
@@ -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;
diff --git a/src/screens/closeAccount/index.tsx b/src/screens/closeAccount/index.tsx
index e210cf7..aa01fa6 100644
--- a/src/screens/closeAccount/index.tsx
+++ b/src/screens/closeAccount/index.tsx
@@ -37,7 +37,7 @@ function CloseAccountScreen() {
diff --git a/src/screens/home/index.tsx b/src/screens/home/index.tsx
index e2d6d92..e1e9ecf 100644
--- a/src/screens/home/index.tsx
+++ b/src/screens/home/index.tsx
@@ -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 = () => {
<>
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();
+ useFocusEffect(
+ useCallback(() => {
+ StatusBar.setBackgroundColor(
+ visible ? '#295E70' : Colors.secondary30.color,
+ );
+ StatusBar.setBarStyle('light-content');
+ }, [visible]),
+ );
+
return (
diff --git a/src/screens/navigationRoute/index.tsx b/src/screens/navigationRoute/index.tsx
index 09b6211..302eeef 100644
--- a/src/screens/navigationRoute/index.tsx
+++ b/src/screens/navigationRoute/index.tsx
@@ -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 ;
+ return ;
case 'history':
return ;
case 'profile':
diff --git a/src/screens/otherMethod/index.tsx b/src/screens/otherMethod/index.tsx
new file mode 100644
index 0000000..04ec7bd
--- /dev/null
+++ b/src/screens/otherMethod/index.tsx
@@ -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();
+ return (
+
+
+
+ navigation.goBack()}
+ />
+ Metode Lain
+
+
+ );
+}
+
+export default OtherMethodScreen;
diff --git a/src/screens/otherMethod/styles.tsx b/src/screens/otherMethod/styles.tsx
new file mode 100644
index 0000000..60ad96c
--- /dev/null
+++ b/src/screens/otherMethod/styles.tsx
@@ -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;