Apr 8, 2024
0
Level 1
ERROR Failed to submit verification: [Error: Failed to submit verification: Request failed with status code 400]
hooks:
import AsyncStorage from "@react-native-async-storage/async-storage";
import axiosInstance, { getJWTHeader } from "../../../../../../utils/axiosConfig";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigation } from "@react-navigation/native";
async function verifyUser(userToVerify) {
try {
console.log('Verify Data:', userToVerify);
const userStr = await AsyncStorage.getItem("upcare_user");
if (!userStr) {
throw new Error("User not found");
}
const user = JSON.parse(userStr);
const headers = getJWTHeader(user);
const { data } = await axiosInstance.post("/user/profile/submit-verification", userToVerify, { headers });
const updatedUser = { ...user, ...data.verificationData };
await AsyncStorage.setItem('upcare_user', JSON.stringify(updatedUser));
console.log('Stored User Data:', updatedUser); // Log the updated user data
return data.user;
} catch (error) {
throw new Error("Failed to submit verification: " + error.message);
}
}
export const useVerifyUser = () => {
const queryClient = useQueryClient();
const navigation = useNavigation();
return useMutation(
verifyUser,
{
onSuccess: (updatedUser) => {
queryClient.setQueryData(['user'], updatedUser);
navigation.goBack();
},
onError: (error) => {
console.error("Failed to submit verification:", error);
},
onSettled: () => {
queryClient.invalidateQueries(['user']);
},
}
);
};
the handling of submission:
import * as React from 'react';
import { View, StyleSheet, Text, ScrollView, Image, TouchableOpacity, Alert } from 'react-native';
import { Button, Title, Appbar, TouchableRipple } from 'react-native-paper';
import * as ImagePicker from 'expo-image-picker';
import { useForm, Controller } from 'react-hook-form';
import { useNavigation } from '@react-navigation/native';
import { useVerifyUser } from './hooks/useVerifyUser';
const VerificationScreen = () => {
const navigation = useNavigation();
const { control, handleSubmit, setValue } = useForm({
defaultValues: {
verification: {
id1FrontImage: '',
id1BackImage: '',
id2FrontImage: '',
id2BackImage: '',
id3FrontImage: '',
id3BackImage: '',
}
}
});
const verifyUserMutation = useVerifyUser();
const pickImage = async (imageType, idNumber) => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (result && !result.canceled && result.assets && result.assets.length > 0) {
const selectedImageUri = result.assets[0].uri;
setValue(`verification.id${idNumber}${imageType.charAt(0).toUpperCase() + imageType.slice(1)}Image`, selectedImageUri);
}
} catch (error) {
console.error('Image picker error:', error);
Alert.alert('Error', 'Failed to pick image. Please try again.');
}
};
const onSubmit = async (data) => {
try {
await verifyUserMutation.mutateAsync(data);
} catch (error) {
console.error('Failed to submit verification:', error);
Alert.alert('Error', 'Failed to submit verification. Please try again.');
}
};
return (
<View style={{ flex: 1 }}>
<Appbar.Header>
<Appbar.BackAction onPress={() => navigation.goBack()} />
</Appbar.Header>
<ScrollView contentContainerStyle={styles.container}>
{/* ID 1 */}
<View>
<Title>ID 1</Title>
{/* ID 1 Front */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('front', 1)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload front image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id1FrontImage"
/>
{/* ID 1 Back */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('back', 1)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload back image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id1BackImage"
/>
</View>
{/* ID 2 */}
<View>
<Title>ID 2</Title>
{/* ID 2 Front */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('front', 2)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload front image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id2FrontImage"
/>
{/* ID 2 Back */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('back', 2)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload back image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id2BackImage"
/>
</View>
{/* ID 3 */}
<View>
<Title>ID 3</Title>
{/* ID 3 Front */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('front', 3)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload front image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id3FrontImage"
/>
{/* ID 3 Back */}
<Controller
control={control}
render={({ field: { value } }) => (
<View style={styles.imageContainer}>
<TouchableRipple style={styles.imagePicker} onPress={() => pickImage('back', 3)}>
{value ? (
<Image source={{ uri: value }} style={styles.image} />
) : (
<Text style={styles.text}>Tap to upload back image</Text>
)}
</TouchableRipple>
</View>
)}
name="verification.id3BackImage"
/>
</View>
<Button mode="outlined" onPress={handleSubmit(onSubmit)}>Submit</Button>
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
backgroundColor: "#F4F7FB",
},
imageContainer: {
marginVertical: 8,
},
imagePicker: {
backgroundColor: "#0A3480",
alignItems: 'center',
justifyContent: 'center',
height: 150,
borderRadius: 14,
},
image: {
width: '100%',
height: '100%',
resizeMode: 'cover',
borderRadius: 14,
},
text: { color: 'white' }
});
export default VerificationScreen;
backend:
public function submitVerification(Request $request)
{
$user = auth()->user();
$validate = $this->validateRequest($request, $user->role);
if ($validate->fails()) {
return response()->json(['error' => $validate->errors()], 400);
}
$verificationData = $this->getOrCreateVerificationData($user, $request);
if ($request->has('verification') && !empty($request->verification)) {
$this->handleFileAttachments($verificationData, $request->verification, $user->id);
}
$verificationData->status = $request->has('checkStatus') ? 'pending' : 'to be reviewed';
$verificationData->save();
// Get attached images
$attachedImages = $verificationData->getMedia('verification_' . $user->id)->map(function ($media) {
return $media->file_name;
});
$responseData = [
'message' => 'Verification submitted successfully.',
'type' => 'success',
'verificationData' => $verificationData,
'attachedImages' => $attachedImages,
];
return response()->json($responseData, 200);
}
private function validateRequest(Request $request, $role)
{
$rules = ['verification.*' => ['required', 'image']];
if ($role === 'user') {
$rules = array_merge($rules, [
'verification' => ['array', 'min:2', 'required'],
'checkStatus' => 'nullable',
'verificationID' => 'nullable',
]);
} else {
$rules = array_merge($rules, [
'link' => 'nullable',
'checkStatus' => 'nullable',
'verificationID' => 'nullable',
]);
}
return Validator::make($request->all(), $rules);
}
private function getOrCreateVerificationData($user, Request $request)
{
if ($request->filled('verificationID')) {
$verificationData = UserVerification::find($request->verificationID);
$verificationData->clearMediaCollection('verification_' . $user->id);
} else {
$verificationData = new UserVerification(['user_id' => $user->id]);
if ($user->role !== 'user') {
$verificationData->link = $request->link;
}
$verificationData->save();
}
return $verificationData;
}
private function handleFileAttachments($verificationData, $files, $userId)
{
foreach ($files as $index => $data) {
$verificationData->attachUserID($data, $index, $userId);
}
}
tho the back end is functioning well Im having problem in sending data to the serve from client to server side what might be the problem help please
Please or to participate in this conversation.