Finalized all of the passport application flow feature and and adding a feature to add data
This commit is contained in:
@ -7,6 +7,12 @@ import {Button} from 'react-native-paper';
|
||||
import Colors from '../../../../../assets/styles/Colors';
|
||||
import jobData from '../../../../data/DropdownData/JobData';
|
||||
import nationalityData from '../../../../data/DropdownData/NationalityData';
|
||||
import {PassportAppointment} from '../../../../navigation/type';
|
||||
import {
|
||||
addData,
|
||||
getData,
|
||||
storeData,
|
||||
} from '../../../../helper/asyncStorageHelper';
|
||||
|
||||
const Step4DataConfirmationSubStep2 = ({
|
||||
setStep,
|
||||
@ -148,7 +154,49 @@ const Step4DataConfirmationSubStep2 = ({
|
||||
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={() => setStep(5)}
|
||||
onPress={async () => {
|
||||
// Ambil data appointment yang sudah tersimpan
|
||||
const storedAppointments: PassportAppointment[] =
|
||||
(await getData('passportAppointments')) || [];
|
||||
|
||||
// Ambil ID terakhir dan hitung ID baru
|
||||
const lastId = storedAppointments.length
|
||||
? Math.max(...storedAppointments.map(item => Number(item.id)))
|
||||
: 0;
|
||||
const nextId = (lastId + 1).toString();
|
||||
|
||||
// Buat appointment baru dengan ID yang sudah dihitung
|
||||
const newAppointment: PassportAppointment = {
|
||||
id: nextId,
|
||||
applicantName: 'Salwa Aisyah Adhani',
|
||||
applicantCode: '1038000008887777',
|
||||
appointmentDate: 'Selasa, 20 Mei 2025',
|
||||
appointmentTime: '10:00-11:00 WIB',
|
||||
serviceUnit: 'Kantor Imigrasi Depok',
|
||||
status: 'Menunggu Pembayaran',
|
||||
submissionDate: 'Kamis, 15 Mei 2025 21:30',
|
||||
serviceCode: 'EH-LP7RNC',
|
||||
applicationDetails: {
|
||||
nationalIdNumber: '3271234560009123456',
|
||||
gender: 'Wanita',
|
||||
applicationType: 'Penggantian Paspor',
|
||||
replacementReason: 'Penuh/Halaman Penuh',
|
||||
applicationPurpose: 'Wisata/Liburan',
|
||||
passportType: 'PASPOR ELEKTRONIK POLIKARBONAT 5 TAHUN',
|
||||
fee: '650.000',
|
||||
},
|
||||
};
|
||||
|
||||
// Simpan appointment baru
|
||||
await addData<PassportAppointment>(
|
||||
'passportAppointments',
|
||||
newAppointment,
|
||||
);
|
||||
|
||||
const updatedAppointments = await getData('passportAppointments');
|
||||
console.log('Data yang berhasil ditambahkan:', updatedAppointments);
|
||||
setStep(5);
|
||||
}}
|
||||
style={[styles.subStepButtonContained, {marginBottom: 8}]}
|
||||
textColor={Colors.neutral100.color}>
|
||||
Simpan Draft
|
||||
|
@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View, Text, Pressable} from 'react-native';
|
||||
import {Button} from 'react-native-paper';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Colors from '../../../../../assets/styles/Colors';
|
||||
import styles from '../styles';
|
||||
import {getData} from '../../../../helper/asyncStorageHelper';
|
||||
import {PassportAppointment} from '../../../../navigation/type';
|
||||
|
||||
type Step5VerificationProps = {
|
||||
setStep: (step: number) => void;
|
||||
@ -15,8 +17,23 @@ type Step5VerificationProps = {
|
||||
const Step5Content = (props: Step5VerificationProps) => {
|
||||
const {setStep, setSubStep, passportAppointmentData, showEditDataSheet} =
|
||||
props;
|
||||
const lastAppointment =
|
||||
passportAppointmentData[passportAppointmentData.length - 1];
|
||||
|
||||
const [lastAppointment, setLastAppointment] =
|
||||
useState<PassportAppointment>();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const data = await getData('passportAppointments');
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
setLastAppointment(data[data.length - 1]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data: ', error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View style={styles.subStepContainer}>
|
||||
@ -36,7 +53,7 @@ const Step5Content = (props: Step5VerificationProps) => {
|
||||
styles.applicantDetailTextDesc,
|
||||
{textTransform: 'uppercase', flex: 0},
|
||||
]}>
|
||||
{lastAppointment.applicantName}
|
||||
{lastAppointment?.applicantName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailIconContentWrapper}>
|
||||
@ -63,27 +80,27 @@ const Step5Content = (props: Step5VerificationProps) => {
|
||||
<View style={styles.applicantDetailContentChildContainer}>
|
||||
<DetailRow
|
||||
label="NIK"
|
||||
value={lastAppointment.applicationDetails.nationalIdNumber}
|
||||
value={lastAppointment?.applicationDetails?.nationalIdNumber}
|
||||
/>
|
||||
<DetailRow
|
||||
label="Jenis Kelamin"
|
||||
value={lastAppointment.applicationDetails.gender}
|
||||
value={lastAppointment?.applicationDetails?.gender}
|
||||
/>
|
||||
<DetailRow
|
||||
label="Jenis Permohonan"
|
||||
value={lastAppointment.applicationDetails.applicationType}
|
||||
value={lastAppointment?.applicationDetails?.applicationType}
|
||||
/>
|
||||
<DetailRow
|
||||
label="Alasan Penggantian"
|
||||
value={lastAppointment.applicationDetails.replacementReason}
|
||||
value={lastAppointment?.applicationDetails?.replacementReason}
|
||||
/>
|
||||
<DetailRow
|
||||
label="Tujuan Permohonan"
|
||||
value={lastAppointment.applicationDetails.applicationPurpose}
|
||||
value={lastAppointment?.applicationDetails?.applicationPurpose}
|
||||
/>
|
||||
<DetailRow
|
||||
label="Jenis Paspor"
|
||||
value={lastAppointment.applicationDetails.passportType}
|
||||
value={lastAppointment?.applicationDetails?.passportType}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@ -110,7 +127,7 @@ const Step5Content = (props: Step5VerificationProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DetailRow = ({label, value}: {label: string; value: string}) => (
|
||||
const DetailRow = ({label, value}: {label: string; value: string | undefined}) => (
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
<Text style={styles.applicantDetailTextTitle}>{label}</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>{value}</Text>
|
||||
|
@ -6,16 +6,22 @@ import styles from '../styles';
|
||||
import Colors from '../../../../../assets/styles/Colors';
|
||||
import FontFamily from '../../../../../assets/styles/FontFamily';
|
||||
import arrivalDateGuidelinesData from '../../../../data/Steps/ArrivalDateGuidelinesData';
|
||||
import passportTypeData from '../../../../data/DropdownData/PassportTypeData';
|
||||
|
||||
type Step6ProcessingProps = {
|
||||
showFinalizationConfirmationDialog: () => void;
|
||||
showPassportTypeInfoDialog: () => void;
|
||||
showSearchLocationSheet: () => void;
|
||||
showSelectDateSheet: () => void;
|
||||
};
|
||||
|
||||
const Step6Processing = (props: Step6ProcessingProps) => {
|
||||
const {showFinalizationConfirmationDialog, showPassportTypeInfoDialog, showSearchLocationSheet} =
|
||||
props;
|
||||
const {
|
||||
showFinalizationConfirmationDialog,
|
||||
showPassportTypeInfoDialog,
|
||||
showSearchLocationSheet,
|
||||
showSelectDateSheet,
|
||||
} = props;
|
||||
return (
|
||||
<ScrollView>
|
||||
<View style={styles.subStepContainer}>
|
||||
@ -30,13 +36,12 @@ const Step6Processing = (props: Step6ProcessingProps) => {
|
||||
</View>
|
||||
|
||||
<View style={[styles.subStepTextInputContainer, {marginVertical: 16}]}>
|
||||
{/* Trigger Search Location Bottom Sheet */}
|
||||
<TextInputComponent
|
||||
title="Lokasi Kantor Imigrasi"
|
||||
placeholder="Pilih lokasi kantor imigrasi"
|
||||
isRequired
|
||||
isDropdownSearchLocation
|
||||
handlePressSearchLocation={showSearchLocationSheet}
|
||||
isDropdownPressedSheet
|
||||
handleDropdownPressed={showSearchLocationSheet}
|
||||
/>
|
||||
<TextInputComponent
|
||||
title="Jenis Paspor"
|
||||
@ -44,6 +49,7 @@ const Step6Processing = (props: Step6ProcessingProps) => {
|
||||
placeholder="Pilih satu jenis paspor"
|
||||
isRequired
|
||||
isDropdown
|
||||
dropdownItemData={passportTypeData}
|
||||
onIconButtonPress={showPassportTypeInfoDialog}
|
||||
/>
|
||||
</View>
|
||||
@ -80,12 +86,12 @@ const Step6Processing = (props: Step6ProcessingProps) => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* TODO: Add calendar functionality here. */}
|
||||
<TextInputComponent
|
||||
title="Tanggal dan Waktu Kedatangan"
|
||||
placeholder="Pilih tanggal dan waktu kedatangan"
|
||||
isRequired
|
||||
isDate
|
||||
isDropdownPressedSheet
|
||||
handleDropdownPressed={showSelectDateSheet}
|
||||
/>
|
||||
|
||||
<Button
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import {Button, Divider, Text} from 'react-native-paper';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Colors from '../../../../../assets/styles/Colors';
|
||||
import styles from '../styles';
|
||||
import passportAppointmentData from '../../../../data/History/PassportAppointmentData';
|
||||
import Accordion from '../../../../components/Accordion';
|
||||
import termsAndConditionsData from '../../../../data/Steps/TermsAndContionsData';
|
||||
import {PassportAppointment} from '../../../../navigation/type';
|
||||
import {getData} from '../../../../helper/asyncStorageHelper';
|
||||
|
||||
type Step7CompletionProps = {
|
||||
showSubmitSuccessDialog: () => void;
|
||||
@ -15,8 +16,21 @@ type Step7CompletionProps = {
|
||||
|
||||
const Step7Completion = (props: Step7CompletionProps) => {
|
||||
const {showSubmitSuccessDialog, setLastCompletedSteps} = props;
|
||||
const lastAppointment =
|
||||
passportAppointmentData[passportAppointmentData.length - 1];
|
||||
const [lastAppointment, setLastAppointment] = useState<PassportAppointment>();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const data = await getData('passportAppointments');
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
setLastAppointment(data[data.length - 1]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data: ', error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
@ -31,7 +45,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{lastAppointment.appointmentDate}
|
||||
{lastAppointment?.appointmentDate}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
@ -41,7 +55,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{lastAppointment.appointmentTime}
|
||||
{lastAppointment?.appointmentTime}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midIconContentWrapper}>
|
||||
@ -51,7 +65,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midIconContentTextStyle}>
|
||||
{lastAppointment.serviceUnit}
|
||||
{lastAppointment?.serviceUnit}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
@ -60,13 +74,13 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>Tanggal Pengajuan</Text>
|
||||
<Text style={styles.midTextContentData}>
|
||||
{lastAppointment.submissionDate}
|
||||
{lastAppointment?.submissionDate}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.midTextContentWrapper}>
|
||||
<Text style={styles.midTextContentTitle}>Kode Layanan</Text>
|
||||
<Text style={styles.midTextContentData}>
|
||||
{lastAppointment.serviceCode}
|
||||
{lastAppointment?.serviceCode}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
@ -130,7 +144,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
styles.applicantDetailTextDesc,
|
||||
styles.applicantDetailTexDescName,
|
||||
]}>
|
||||
{lastAppointment.applicantName}
|
||||
{lastAppointment?.applicantName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
@ -140,20 +154,20 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
styles.applicantDetailTextDesc,
|
||||
styles.applicantDetailTexDescCode,
|
||||
]}>
|
||||
{lastAppointment.applicantCode}
|
||||
{lastAppointment?.applicantCode}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailContentChildContainer}>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
<Text style={styles.applicantDetailTextTitle}>NIK</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.nationalIdNumber}
|
||||
{lastAppointment?.applicationDetails?.nationalIdNumber}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
<Text style={styles.applicantDetailTextTitle}>Jenis Kelamin</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.gender}
|
||||
{lastAppointment?.applicationDetails?.gender}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
@ -161,7 +175,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
Jenis Permohonan
|
||||
</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.applicationType}
|
||||
{lastAppointment?.applicationDetails?.applicationType}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
@ -169,7 +183,7 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
Alasan Penggantian
|
||||
</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.replacementReason}
|
||||
{lastAppointment?.applicationDetails?.replacementReason}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
@ -177,16 +191,23 @@ const Step7Completion = (props: Step7CompletionProps) => {
|
||||
Tujuan Permohonan
|
||||
</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.applicationPurpose}
|
||||
{lastAppointment?.applicationDetails?.applicationPurpose}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.applicantDetailTextContentWrapper}>
|
||||
<Text style={styles.applicantDetailTextTitle}>Jenis Paspor</Text>
|
||||
<Text style={styles.applicantDetailTextDesc}>
|
||||
{lastAppointment.applicationDetails.passportType}
|
||||
{lastAppointment?.applicationDetails?.passportType}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Divider style={styles.applicantDetailDividerMargin} />
|
||||
<View style={styles.applicantDetailBottomContentWrapper}>
|
||||
<Text style={styles.applicantDetailBottomText}>Biaya</Text>
|
||||
<Text style={styles.applicantDetailBottomText}>
|
||||
{lastAppointment?.applicationDetails?.fee}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{margin: 16}}>
|
||||
|
@ -200,6 +200,15 @@ const styles = StyleSheet.create({
|
||||
applicantDetailTexDescCode: {
|
||||
textAlign: 'right',
|
||||
},
|
||||
applicantDetailBottomText: {
|
||||
fontSize: 14,
|
||||
...FontFamily.notoSansBold,
|
||||
color: Colors.primary30.color,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
applicantDetailDividerMargin: {
|
||||
marginVertical: 4,
|
||||
},
|
||||
midContainer: {
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
},
|
||||
|
Reference in New Issue
Block a user