Update passport application step flow

This commit is contained in:
Salwa Aisyah
2025-04-27 19:35:00 +07:00
parent 06b8f2ab80
commit a077d93029
37 changed files with 4802 additions and 416 deletions

View File

@ -3,6 +3,8 @@ import WaitingForPaymentIcon from '../../assets/icons/waiting_for_payment.svg';
import {StyleSheet, Text, View} from 'react-native';
import FontFamily from '../../assets/styles/FontFamily';
import Colors from '../../assets/styles/Colors';
import AsyncStorage from '@react-native-async-storage/async-storage';
type PassportAppointmentCardProps = {
applicantName: string | undefined;

View File

@ -40,6 +40,8 @@ interface TextInputComponentProps {
isMultiline?: boolean;
isDropdownPressedSheet?: boolean;
handleDropdownPressed?: () => void;
countryValue?: string | null;
setCountryValue?: (country: string) => void;
}
const TextInputComponent = (props: TextInputComponentProps) => {
@ -61,6 +63,8 @@ const TextInputComponent = (props: TextInputComponentProps) => {
isMultiline = false,
isDropdownPressedSheet = false,
handleDropdownPressed,
countryValue,
setCountryValue,
} = props;
const [secureText, setSecureText] = useState(isPassword);
@ -68,7 +72,6 @@ const TextInputComponent = (props: TextInputComponentProps) => {
const [formattedDate, setFormattedDate] = useState<string>('');
const [showPicker, setShowPicker] = useState(false);
const [dropdownValue, setDropdownValue] = useState(null);
const [country, setCountry] = useState<string | null>(null);
const [searchQuery, setSearchQuery] = useState('');
const filteredItems = dropdownCountryItemData?.filter(item =>
@ -118,7 +121,9 @@ const TextInputComponent = (props: TextInputComponentProps) => {
};
const renderLeftIcon = () => {
const selectedItem = filteredItems?.find(item => item.value === country);
const selectedItem = filteredItems?.find(
item => item.value === countryValue,
);
if (!selectedItem?.image?.uri) return null;
return (
@ -263,14 +268,16 @@ const TextInputComponent = (props: TextInputComponentProps) => {
renderInputSearch={() =>
renderInputSearch(searchQuery, setSearchQuery)
}
value={country}
value={countryValue}
data={filteredItems ?? []}
valueField="value"
labelField="label"
placeholder={placeholder}
searchPlaceholder="Cari"
onChange={item => {
setCountry(item.value);
if (setCountryValue) {
setCountryValue(item.value);
}
}}
disable={isDisabled}
renderRightIcon={() => <Icon name="arrow-drop-down" size={20} />}

View File

@ -1,9 +1,4 @@
const countryData = [
{
value: '1',
label: 'Indonesia',
image: {uri: 'https://flagcdn.com/w320/id.png'},
},
{
value: '2',
label: 'United States',

View File

@ -67,7 +67,7 @@ function HistoryScreen() {
return (
<View style={styles.container}>
{showNavBackAppBar ? (
{showNavBackAppBar ? (
<View style={styles.appBarNavBackContainer}>
<Icon
name="arrow-left"

View File

@ -72,6 +72,8 @@ type RenderApplicationStepsContentProps = {
showEditDataSheet: () => void;
showSearchLocationSheet: () => void;
showSelectDateSheet: () => void;
selectedDestinationCountryOption: string;
setSelectedDestinationCountryOption: (val: string) => void;
};
const RenderApplicationStepsContent = (
@ -86,6 +88,8 @@ const RenderApplicationStepsContent = (
setSelectedOption,
selectedPassportOption,
setSelectedPassportOption,
selectedDestinationCountryOption,
setSelectedDestinationCountryOption,
checkedOption,
setCheckedOption,
showDontHaveYetDialog,
@ -162,14 +166,17 @@ const RenderApplicationStepsContent = (
setSubStep={setSubStep}
selectedOption={selectedOption}
setSelectedOption={setSelectedOption}
selectedPassportOption={selectedPassportOption}
/>
);
case 7:
return (
<Step2PassportApplicationQuestionnaireSubStep7
setSubStep={setSubStep}
selectedOption={selectedOption}
setSelectedOption={setSelectedOption}
selectedDestinationCountryOption={selectedDestinationCountryOption}
setSelectedDestinationCountryOption={
setSelectedDestinationCountryOption
}
/>
);
case 8:
@ -189,7 +196,9 @@ const RenderApplicationStepsContent = (
case 10:
return (
<Step2PassportApplicationQuestionnaireSubStep10
setStep={setStep}
setSubStep={setSubStep}
selectedDestinationCountryOption={selectedDestinationCountryOption}
/>
);
case 11:
@ -236,6 +245,7 @@ const RenderApplicationStepsContent = (
showCivilStatusDocumentsInfoDialog={
showCivilStatusDocumentsInfoDialog
}
selectedDestinationCountryOption={selectedDestinationCountryOption}
/>
);
case 5:
@ -321,6 +331,10 @@ function RegularPassportScreen() {
// State management
const [selectedOption, setSelectedOption] = useState('');
const [selectedPassportOption, setSelectedPassportOption] = useState('');
const [
selectedDestinationCountryOption,
setSelectedDestinationCountryOption,
] = useState('');
const [checkedOption, setCheckedOption] = useState(false);
const [showApplicationStepsContent, setShowApplicationStepsContent] =
useState(false);
@ -477,6 +491,10 @@ function RegularPassportScreen() {
setSelectedOption={setSelectedOption}
selectedPassportOption={selectedPassportOption}
setSelectedPassportOption={setSelectedPassportOption}
selectedDestinationCountryOption={selectedDestinationCountryOption}
setSelectedDestinationCountryOption={
setSelectedDestinationCountryOption
}
checkedOption={checkedOption}
setCheckedOption={setCheckedOption}
showDontHaveYetDialog={showDontHaveYetDialog}
@ -501,7 +519,7 @@ function RegularPassportScreen() {
<DialogDontHaveYetPassport
visible={visibleDontHaveYetDialog}
onClose={hideDontHaveYetDialog}
onContinue={() => setSubStep(2)}
onContinue={() => setSubStep(6)}
/>
)}

View File

@ -8,17 +8,24 @@ import Colors from '../../../../../assets/styles/Colors';
import familyRelationshipData from '../../../../data/DropdownData/FamilyRelationshipData';
type Step2PassportApplicationQuestionnaireSubStep10Props = {
selectedDestinationCountryOption: string;
setStep: (step: number) => void;
setSubStep: (step: number) => void;
};
const Step2PassportApplicationQuestionnaireSubStep10 = ({
setSubStep,
}: Step2PassportApplicationQuestionnaireSubStep10Props) => {
const Step2PassportApplicationQuestionnaireSubStep10 = (
props: Step2PassportApplicationQuestionnaireSubStep10Props,
) => {
const {selectedDestinationCountryOption, setStep, setSubStep} = props;
return (
<ScrollView>
<View style={styles.subStepContainer}>
<Pressable
onPress={() => setSubStep(9)}
onPress={() => {
selectedDestinationCountryOption === 'destination_country_not_set'
? setSubStep(7)
: setSubStep(9);
}}
style={({pressed}) => [
styles.subStepButtonBackWrapper,
{
@ -59,7 +66,11 @@ const Step2PassportApplicationQuestionnaireSubStep10 = ({
<Button
mode="contained"
onPress={() => setSubStep(11)}
onPress={() => {
selectedDestinationCountryOption === 'destination_country_not_set'
? setStep(3)
: setSubStep(11);
}}
style={styles.subStepButtonContained}
textColor={Colors.neutral100.color}>
Lanjut

View File

@ -11,18 +11,27 @@ type Step2PassportApplicationQuestionnaireSubStep6Props = {
setSubStep: (step: number) => void;
selectedOption: string;
setSelectedOption: (val: string) => void;
selectedPassportOption: string;
};
const Step2PassportApplicationQuestionnaireSubStep6 = ({
setSubStep,
selectedOption,
setSelectedOption,
}: Step2PassportApplicationQuestionnaireSubStep6Props) => {
const Step2PassportApplicationQuestionnaireSubStep6 = (
props: Step2PassportApplicationQuestionnaireSubStep6Props,
) => {
const {
setSubStep,
selectedOption,
setSelectedOption,
selectedPassportOption,
} = props;
return (
<ScrollView>
<View style={styles.subStepContainer}>
<Pressable
onPress={() => setSubStep(5)}
onPress={() => {
selectedPassportOption === 'already'
? setSubStep(5)
: setSubStep(1);
}}
style={({pressed}) => [
styles.subStepButtonBackWrapper,
{

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, {useState} from 'react';
import {ScrollView, View, Text, Pressable} from 'react-native';
import Icon from 'react-native-vector-icons/Feather';
import {Button} from 'react-native-paper';
@ -11,20 +11,46 @@ import countryData from '../../../../data/DropdownData/CountryData';
type Step2PassportApplicationQuestionnaireSubStep7Props = {
setSubStep: (step: number) => void;
selectedOption: string;
setSelectedOption: (val: string) => void;
selectedDestinationCountryOption: string;
setSelectedDestinationCountryOption: (val: string) => void;
};
const Step2PassportApplicationQuestionnaireSubStep7 = ({
setSubStep,
selectedOption,
setSelectedOption,
selectedDestinationCountryOption,
setSelectedDestinationCountryOption,
}: Step2PassportApplicationQuestionnaireSubStep7Props) => {
const [countryValue, setCountryValue] = useState<string | null>(null);
const handleCountrySelect = (value: string | null) => {
setCountryValue(value);
setSelectedDestinationCountryOption('');
};
const handleRadioSelect = (value: string) => {
if (value === 'destination_country_not_set') {
setSelectedDestinationCountryOption(value);
setCountryValue(null);
} else {
setSelectedDestinationCountryOption(value);
}
};
const isRadioButtonSelected = (value: string) => {
if (countryValue !== null) {
return '';
}
return selectedDestinationCountryOption === value ? value : '';
};
return (
<ScrollView>
<View style={styles.subStepContainer}>
<Pressable
onPress={() => setSubStep(6)}
onPress={() => {
setSubStep(6);
setSelectedDestinationCountryOption('');
}}
style={({pressed}) => [
styles.subStepButtonBackWrapper,
{
@ -41,6 +67,8 @@ const Step2PassportApplicationQuestionnaireSubStep7 = ({
placeholder="Masukkan negara tujuan"
isDropdownCountry
dropdownCountryItemData={countryData}
countryValue={countryValue}
setCountryValue={handleCountrySelect}
/>
{destinationCountryOptions.map(option => (
<RadioButtonOptionComponent
@ -48,15 +76,19 @@ const Step2PassportApplicationQuestionnaireSubStep7 = ({
label={option.label}
description={option.description}
value={option.value}
selectedValue={selectedOption}
onSelect={value => setSelectedOption(value)}
selectedValue={isRadioButtonSelected(option.value)}
onSelect={() => handleRadioSelect(option.value)}
/>
))}
</View>
<Button
mode="contained"
onPress={() => setSubStep(8)}
onPress={() => {
selectedDestinationCountryOption === 'destination_country_not_set'
? setSubStep(10)
: setSubStep(8);
}}
style={styles.subStepButtonContained}
textColor={Colors.neutral100.color}>
Lanjut

View File

@ -23,6 +23,7 @@ interface Step3UploadDocumentsProps {
setStep: (step: number) => void;
setSubStep: (subStep: number) => void;
selectedPassportOption: string;
selectedDestinationCountryOption: string;
showCivilStatusDocumentsInfoDialog: () => void;
}
@ -137,6 +138,7 @@ const Step3UploadDocuments = (props: Step3UploadDocumentsProps) => {
setStep,
setSubStep,
selectedPassportOption,
selectedDestinationCountryOption,
showCivilStatusDocumentsInfoDialog,
} = props;
return (
@ -145,7 +147,11 @@ const Step3UploadDocuments = (props: Step3UploadDocumentsProps) => {
<BackButton
onPress={() => {
setStep(2);
setSubStep(11);
setSubStep(
selectedDestinationCountryOption === 'destination_country_not_set'
? 10
: 11,
);
}}
/>
@ -153,11 +159,11 @@ const Step3UploadDocuments = (props: Step3UploadDocumentsProps) => {
<Text style={styles.subStepDesc}>
Layanan yang cocok untuk Anda adalah{' '}
{selectedPassportOption !== 'already' ? (
<Text style={{...FontFamily.notoSansBold}}>Paspor Baru</Text>
) : (
<Text style={{...FontFamily.notoSansBold}}>
Paspor Penggantian
</Text>
) : (
<Text style={{...FontFamily.notoSansBold}}>Paspor Baru</Text>
)}
. Silakan unggah kelengkapan dokumen berikut.
</Text>
@ -244,7 +250,7 @@ const Step3UploadDocuments = (props: Step3UploadDocumentsProps) => {
showCivilStatusDocumentsInfoDialog
}
/>
{selectedPassportOption !== 'already' && (
{selectedPassportOption === 'already' && (
<DocumentUploadSection title="Paspor Lama" isRequired />
)}
</View>