Add UI on Guidebook screen. Then, add Application Guide and Passport Requirements screens

This commit is contained in:
Mochammad Adhi Buchori
2025-04-23 18:34:18 +07:00
parent 5f513257d6
commit dbcdc6480d
18 changed files with 295 additions and 158 deletions

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 15H17V17H11V15ZM9 7H7V9H9V7ZM11 13H17V11H11V13ZM11 9H17V7H11V9ZM9 11H7V13H9V11ZM21 5V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V5C3 3.9 3.9 3 5 3H19C20.1 3 21 3.9 21 5ZM19 5H5V19H19V5ZM9 15H7V17H9V15Z" fill="#2B3A51"/>
</svg>

After

Width:  |  Height:  |  Size: 338 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 23C5.45 23 4.97917 22.8042 4.5875 22.4125C4.19583 22.0208 4 21.55 4 21V3C4 2.45 4.19583 1.97917 4.5875 1.5875C4.97917 1.19583 5.45 1 6 1H16C16.55 1 17.0208 1.19583 17.4125 1.5875C17.8042 1.97917 18 2.45 18 3V7H16V6H6V18H16V17H18V21C18 21.55 17.8042 22.0208 17.4125 22.4125C17.0208 22.8042 16.55 23 16 23H6ZM6 20V21H16V20H6ZM14.95 16L10.7 11.75L12.1 10.35L14.95 13.2L20.6 7.55L22 8.95L14.95 16ZM6 4H16V3H6V4Z" fill="#2B3A51"/>
</svg>

After

Width:  |  Height:  |  Size: 541 B

View File

@ -18,6 +18,8 @@ import ExpressPassportScreen from '../screens/expressPassport';
import GuidebookScreen from '../screens/guidebook';
import EazyPassportScreen from '../screens/eazyPassport';
import ApplicationDetailScreen from '../screens/applicationDetail';
import PassportRequirementsScreen from '../screens/passportRequirements';
import ApplicationGuideScreen from '../screens/applicationGuide';
const Stack = createNativeStackNavigator<RootStackParamList>();
@ -107,6 +109,16 @@ function RootStack() {
component={ApplicationDetailScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="ApplicationGuide"
component={ApplicationGuideScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="PassportRequirements"
component={PassportRequirementsScreen}
options={{headerShown: false}}
/>
</Stack.Navigator>
);
}

View File

@ -18,4 +18,6 @@ export type RootStackParamList = {
Guidebook: undefined;
EazyPassport: undefined;
ApplicationDetail: {data: PassportAppointmentData};
ApplicationGuide: undefined;
PassportRequirements: undefined;
};

View File

@ -18,6 +18,7 @@ const styles = StyleSheet.create({
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,

View File

@ -0,0 +1,38 @@
import React from 'react';
import {StatusBar, Text, View} from 'react-native';
import styles from './styles';
import Colors from '../../../assets/styles/Colors';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { RootStackParamList } from '../../navigation/type';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
type ApplicationGuideScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'ApplicationGuide'
>;
function ApplicationGuideScreen() {
const navigation = useNavigation<ApplicationGuideScreenNavigationProp>();
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}>Panduan Aplikasi</Text>
</View>
</View>
);
}
export default ApplicationGuideScreen;

View 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: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,
},
appBarContainer: {
height: 64,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: Colors.neutral100.color,
},
});
export default styles;

View File

@ -12,6 +12,7 @@ const styles = StyleSheet.create({
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,

View File

@ -16,12 +16,14 @@ const styles = StyleSheet.create({
fontSize: 12,
includeFontPadding: false,
textAlign: 'justify',
lineHeight: 24,
},
appBarTitle: {
color: Colors.neutral100.color,
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,

View File

@ -11,6 +11,7 @@ const styles = StyleSheet.create({
color: Colors.neutral100.color,
...FontFamily.notoSansRegular,
fontSize: 22,
includeFontPadding: false,
marginStart: 16,
},
appBarIcon: {

View File

@ -1,160 +1,11 @@
import React, {useState} from 'react';
import {Button, Text, View} from 'react-native';
import React from 'react';
import {Text, View} from 'react-native';
import styles from './styles';
import Colors from '../../../assets/styles/Colors';
import StepIndicator from '../../components/StepIndicator';
const renderContent = (
step: number,
subStep: number,
setStep: (step: number) => void,
setSubStep: (step: number) => void,
) => {
if (step === 1) {
switch (subStep) {
case 1:
return (
<View>
<Text>Step 1.1</Text>
<Button title="Next" onPress={() => setSubStep(2)} />
</View>
);
case 2:
return (
<View>
<Text>Step 1.2</Text>
<Button title="Next" onPress={() => setSubStep(3)} />
<Button title="Back" onPress={() => setSubStep(1)} />
</View>
);
case 3:
return (
<View>
<Text>Step 1.3</Text>
<Button
title="Next"
onPress={() => {
setStep(2);
setSubStep(1);
}}
/>
<Button title="Back" onPress={() => setSubStep(2)} />
</View>
);
default:
return null;
}
}
if (step === 2) {
switch (subStep) {
case 1:
return (
<View>
<Text>Step 2.1</Text>
<Button title="Next" onPress={() => setSubStep(2)} />
<Button
title="Back"
onPress={() => {
setStep(1);
setSubStep(3);
}}
/>
</View>
);
case 2:
return (
<View>
<Text>Step 2.2</Text>
<Button title="Next" onPress={() => setSubStep(3)} />
<Button title="Back" onPress={() => setSubStep(1)} />
</View>
);
case 3:
return (
<View>
<Text>Step 2.3</Text>
<Button
title="Next"
onPress={() => {
setStep(3);
setSubStep(1);
}}
/>
<Button title="Back" onPress={() => setSubStep(2)} />
</View>
);
default:
return null;
}
}
switch (step) {
case 3:
return (
<View>
<Button title="Next" onPress={() => setStep(4)} />
<Button title="Back" onPress={() => setStep(2)} />
</View>
);
case 4:
return (
<View>
<Button title="Next" onPress={() => setStep(5)} />
<Button title="Back" onPress={() => setStep(3)} />
</View>
);
case 5:
return (
<View>
<Button title="Next" onPress={() => setStep(6)} />
<Button title="Back" onPress={() => setStep(4)} />
</View>
);
case 6:
return (
<View>
<Button title="Next" onPress={() => setStep(7)} />
<Button title="Back" onPress={() => setStep(5)} />
</View>
);
case 7:
return (
<View>
<Button title="Back" onPress={() => setStep(6)} />
</View>
);
default:
return null;
}
};
function ExpressPassportScreen() {
const [step, setStep] = useState(1);
const [subStep, setSubStep] = useState(1);
const completedSteps = [...Array(step - 1)].map((_, i) => i + 1);
const stepTitles: {[key: number]: string} = {
1: 'Informasi Pribadi',
2: 'Dokumen Pendukung',
3: 'Pembayaran',
4: 'Konfirmasi Data',
5: 'Verifikasi',
6: 'Pemrosesan',
7: 'Selesai',
};
return (
<View style={{flex: 1}}>
<View>
<Text>{stepTitles[step]}</Text>
</View>
<StepIndicator
currentStep={step}
totalSteps={7}
completedSteps={completedSteps}
/>
{renderContent(step, subStep, setStep, setSubStep)}
<View style={styles.container}>
<Text>Express Passport Screen</Text>
</View>
);
}

View File

@ -1,11 +1,81 @@
import React from 'react';
import {Text, View} from 'react-native';
import {Pressable, StatusBar, Text, View} from 'react-native';
import styles from './styles';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import Colors from '../../../assets/styles/Colors';
import {RootStackParamList} from '../../navigation/type';
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {useNavigation} from '@react-navigation/native';
import ApplicationGuideIcon from '../../../assets/icons/mobile_friendly.svg';
import PassportRequirementsIcon from '../../../assets/icons/list_box_outline.svg';
type GuidebookScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'Guidebook'
>;
function GuidebookScreen() {
const navigation = useNavigation<GuidebookScreenNavigationProp>();
return (
<View style={styles.container}>
<Text>Guidebook Screen</Text>
<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()}
/>
<Text style={styles.appBarTitle}>Buku Panduan</Text>
</View>
<View style={styles.contentContainer}>
<Pressable
style={({pressed}) => [
styles.guidebookMenuWrapper,
{
transform: [{scale: pressed ? 0.975 : 1}],
},
]}
onPress={() => navigation.navigate('ApplicationGuide')}>
<View style={styles.guidebookMenuContentWrapper}>
<ApplicationGuideIcon />
<View style={styles.guidebookMenuTextWrapper}>
<Text style={styles.guidebookMenuTextTitle}>
Panduan Aplikasi
</Text>
<Text style={styles.guidebookMenuTextDesc}>
Panduan penggunaan aplikasi M-Paspor
</Text>
</View>
</View>
<Icon name="menu-right" size={24} />
</Pressable>
<Pressable
style={({pressed}) => [
styles.guidebookMenuWrapper,
{
transform: [{scale: pressed ? 0.975 : 1}],
},
]}
onPress={() => navigation.navigate('PassportRequirements')}>
<View style={styles.guidebookMenuContentWrapper}>
<PassportRequirementsIcon />
<View style={styles.guidebookMenuTextWrapper}>
<Text style={styles.guidebookMenuTextTitle}>
Persyaratan Paspor
</Text>
<Text style={styles.guidebookMenuTextDesc}>
Persyaratan seputar pengajuan paspor
</Text>
</View>
</View>
<Icon name="menu-right" size={24} />
</Pressable>
</View>
</View>
);
}

View File

@ -1,12 +1,69 @@
import {StyleSheet} from 'react-native';
import Colors from '../../../assets/styles/Colors';
import FontFamily from '../../../assets/styles/FontFamily';
const styles = StyleSheet.create({
container: {
flex: 1,
alignContent: 'center',
backgroundColor: Colors.neutral100.color,
},
appBarTitle: {
color: Colors.neutral100.color,
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,
},
appBarContainer: {
height: 64,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
justifyContent: 'center',
backgroundColor: Colors.secondary30.color,
},
topContainer: {
backgroundColor: Colors.secondary30.color,
height: 85,
alignItems: 'center',
},
contentContainer: {
margin: 16,
gap: 16,
},
guidebookMenuContainer: {
gap: 16,
},
guidebookMenuWrapper: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
height: 90,
padding: 16,
borderWidth: 1,
borderRadius: 20,
borderColor: Colors.secondary70.color,
},
guidebookMenuContentWrapper: {
flexDirection: 'row',
alignItems: 'center',
gap: 16,
},
guidebookMenuTextWrapper: {
gap: 6,
},
guidebookMenuTextTitle: {
...FontFamily.notoSansMedium,
fontSize: 14,
includeFontPadding: false,
color: Colors.primary30.color,
},
guidebookMenuTextDesc: {
...FontFamily.notoSansRegular,
fontSize: 11,
includeFontPadding: false,
color: Colors.primary40.color,
},
});

View File

@ -12,6 +12,7 @@ const styles = StyleSheet.create({
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,

View File

@ -0,0 +1,37 @@
import React from 'react';
import {StatusBar, Text, View} from 'react-native';
import styles from './styles';
import Colors from '../../../assets/styles/Colors';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {RootStackParamList} from '../../navigation/type';
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {useNavigation} from '@react-navigation/native';
type PassportRequirementsScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'PassportRequirements'
>;
function PassportRequirementsScreen() {
const navigation = useNavigation<PassportRequirementsScreenNavigationProp>();
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}>Persyaratan Paspor</Text>
</View>
</View>
);
}
export default PassportRequirementsScreen;

View 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: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,
},
appBarContainer: {
height: 64,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: Colors.neutral100.color,
},
});
export default styles;

View File

@ -12,6 +12,7 @@ const styles = StyleSheet.create({
...FontFamily.notoSansRegular,
fontSize: 16,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,

View File

@ -12,6 +12,7 @@ const styles = StyleSheet.create({
...FontFamily.notoSansRegular,
fontSize: 22,
marginStart: 16,
includeFontPadding: false,
},
appBarIcon: {
marginLeft: 16,