Files
Dabur_StoreDNA1/src/screens/MainScreen/Feedback/feedbackdummy.js
T
2025-07-30 10:35:06 +05:30

334 lines
13 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import {
View,
Text,
TextInput,
ScrollView,
TouchableOpacity,
Platform,
Image,
Modal,
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import ModalSelector from 'react-native-modal-selector';
import MultiSelect from 'react-native-multiple-select';
import CustomHeader from '../../../components/CustomHeader';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import CustomButton from '../../../components/CustomButton';
import { styles } from './style';
import { toastError, toastSuccess } from '../../../constants/Toast';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import mockDataFlat1 from './data.json';
import CustomCamera from '../../../components/CustomCamera';
import CustomModal from '../../../components/CustomModal';
import { SafeAreaView } from 'react-native-safe-area-context';
const transformSurveyData = (flatData) => {
const grouped = {};
flatData?.forEach(item => {
if (!grouped[item.QuestionId]) {
grouped[item.QuestionId] = {
QuestionId: item.QuestionId,
Question: item.Question,
QuestionType: item.QuestionTypeNew,
QEnable: item.QEnable,
EnableQuestion: item.EnableQuestion,
DisableQuestion: item.DisableQuestion,
QuestionSequence: item.QuestionSequence,
CategorySequence: item.CategorySequence,
Answers: []
};
}
if (!['Number', 'Text', 'OnlyText'].includes(item.QuestionTypeNew)) {
if (item.AnswerId || item.Answer) {
grouped[item.QuestionId].Answers.push({
AnswerId: item.AnswerId,
Answer: item.Answer
});
}
}
});
return Object.values(grouped).sort((a, b) => a.QuestionSequence - b.QuestionSequence);
};
const FeedbackFormScreen = ({ route, navigation }) => {
const { CategoryId, SurveyId, CategoryName } = route.params || {};
const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState({});
const [enabledQuestions, setEnabledQuestions] = useState({});
const [showCamera, setShowCamera] = useState(false);
const [activeCameraQId, setActiveCameraQId] = useState(null);
// For modal
const [showModal, setShowModal] = useState(false);
const [selectedImg, setSelectedImg] = useState(null);
const [reCapImgModalObj, setReCapImgModalObj] = useState({});
useEffect(() => {
const filtered = mockDataFlat1?.mockDataFlat?.filter(
item => item.CategoryId === CategoryId && item.SurveyId === SurveyId
);
const transformed = transformSurveyData(filtered);
setQuestions(transformed);
const enableMap = {};
transformed.forEach(q => {
enableMap[q.QuestionId] = q.QEnable;
});
setEnabledQuestions(enableMap);
loadSavedAnswers();
}, []);
const loadSavedAnswers = async () => {
try {
const saved = await AsyncStorage.getItem('feedback_answers');
if (saved) setAnswers(JSON.parse(saved));
} catch (e) {
console.warn('Failed to load saved answers');
}
};
const saveAnswers = async () => {
try {
await AsyncStorage.setItem('feedback_answers', JSON.stringify(answers));
const completedRaw = await AsyncStorage.getItem('completed_categories');
let completed = completedRaw ? JSON.parse(completedRaw) : [];
if (!completed.includes(CategoryId)) {
completed.push(CategoryId);
await AsyncStorage.setItem('completed_categories', JSON.stringify(completed));
}
toastSuccess('Success', 'Answers Saved Successfully');
navigation.goBack();
} catch (e) {
toastError('Error', 'Failed to save answers');
}
};
const handleAnswerChange = (questionId, value, enableList = '', disableList = '') => {
setAnswers(prev => ({ ...prev, [questionId]: value }));
const updated = { ...enabledQuestions };
if (disableList) {
disableList.split(',').forEach(id => {
updated[parseInt(id)] = false;
});
}
if (enableList) {
enableList.split(',').forEach(id => {
updated[parseInt(id)] = true;
});
}
setEnabledQuestions(updated);
};
const handleImageCaptured = (photo) => {
if (activeCameraQId) {
setAnswers(prev => ({ ...prev, [activeCameraQId]: photo.uri }));
setSelectedImg(photo.uri);
setShowModal(true);
}
setShowCamera(false);
setActiveCameraQId(null);
};
const openCamera = (questionId) => {
setActiveCameraQId(questionId);
setShowCamera(true);
};
const _OpenCaptureImage_Modal = (imgUri) => {
const isImageCap = imgUri !== '' && imgUri != null;
let { cameraType } = reCapImgModalObj;
return (
<CustomModal
showModal={showModal}
title={'Captured Image'}
message={''}
style={{ alignItems: 'center' }}
hideDefaultClose={true}
>
{isImageCap && (
<View style={{ alignItems: 'center' }}>
<Image
source={{ uri: selectedImg }}
style={{
width: 250,
height: 250,
marginBottom: 10,
borderRadius: 10,
}}
/>
<TouchableOpacity
style={{ marginBottom: 10 }}
onPress={() => {
setShowModal(false);
openCamera(activeCameraQId);
}}
>
<MaterialCommunityIcons name="camera-retake" size={50} color={GlobalTheme.colors.primary} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => setShowModal(false)}
style={{ paddingVertical: 10, paddingHorizontal: 30, backgroundColor: GlobalTheme.colors.primary, borderRadius: 6 }}
>
<Text style={{ color: '#fff' }}>Close</Text>
</TouchableOpacity>
</View>
)}
</CustomModal>
);
};
return (
<KeyboardAwareScrollView style={{ flex: 1 }} contentContainerStyle={{ flexGrow: 1 }}>
<SafeAreaView style={{ flex: 1, backgroundColor: GlobalTheme.colors.white }}>
<CustomHeader
title="Feedback and Rating"
rightIcon={IMAGES.menuIcon}
leftIcon={IMAGES.leftArrowIcon}
onLeftPress={() => navigation.goBack()}
onRightPress={() => navigation.navigate('Dashboard')}
/>
<ScrollView>
<View style={styles.container}>
<View style={styles.cardview}>
<Text style={styles.categoryName}>{CategoryName}</Text>
{questions.map((qtn) => {
if (!enabledQuestions[qtn.QuestionId]) return null;
return (
<View key={qtn.QuestionId} style={styles.questionBlock}>
<Text style={styles.questionText}>{qtn.Question}</Text>
{qtn.QuestionType === 'Single choice list' && (
<ModalSelector
animationType='fade'
optionContainerStyle={{ backgroundColor: '#fff' }}
cancelContainerStyle={{backgroundColor: '#fff' }}
key={qtn.QuestionId}
data={qtn.Answers.map(ans => ({ key: ans.AnswerId, label: ans.Answer }))}
initValue="Select one"
onChange={option => {
const selectedAnswer = option.label;
// Look up the matching full answer entry from mockDataFlat1
const matchedRow = mockDataFlat1.mockDataFlat.find(item =>
item.QuestionId === qtn.QuestionId && item.Answer === selectedAnswer
);
const enableQ = matchedRow?.EnableQuestion || '';
const disableQ = matchedRow?.DisableQuestion || '';
handleAnswerChange(
qtn.QuestionId,
selectedAnswer,
enableQ,
disableQ
);
}}
>
<Text style={styles.selectorBox}>
{answers[qtn.QuestionId] || '---Select option---'}
</Text>
</ModalSelector>
)}
{qtn.QuestionType === 'Multi choice list' && (
<MultiSelect
items={qtn.Answers}
uniqueKey="AnswerId"
displayKey="Answer"
onSelectedItemsChange={(selected) =>
handleAnswerChange(
qtn.QuestionId,
selected,
qtn.EnableQuestion,
qtn.DisableQuestion
)
}
selectedItems={answers[qtn.QuestionId] || []}
selectText="Pick Items"
searchInputPlaceholderText="Search Items..."
searchIcon={<Icon name="search" size={18} color="#888" />}
tagRemoveIconColor="#ccc"
tagBorderColor="#ccc"
tagTextColor="#000"
selectedItemTextColor={GlobalTheme.colors.primary}
selectedItemIconColor="#000"
itemTextColor="#000"
styleMainWrapper={styles.multiSelect}
submitButtonText={'Submit'}
textColor={GlobalTheme.colors.black}
submitButtonColor={GlobalTheme.colors.secondary}
styleItemsContainer={styles.styleItemsContainer}
styleListContainer={styles.styleListContainer}
styleInputGroup={styles.styleInputGroup}
styleDropdownMenuSubsection={styles.styleDropdownMenuSubsection}
styleDropdownMenu={styles.styleDropdownMenu}
/>
)}
{(qtn.QuestionType === 'Text' || qtn.QuestionType === 'OnlyText' || qtn.QuestionType === 'Number') && (
<TextInput
style={styles.textInput}
placeholder="Enter here..."
keyboardType={(qtn.QuestionType == 'Decimal' ? 'decimal-pad' : (qtn.QuestionType == 'Text' || qtn.QuestionType == 'OnlyText' ? 'default' : 'number-pad'))}
value={answers[qtn.QuestionId] || ''}
onChangeText={(text) => handleAnswerChange(qtn.QuestionId, text)}
returnKeyType={(Platform.OS === 'ios') ? 'done' : 'next'}
/>
)}
{qtn.QuestionType === 'Image' && (
<>
<TouchableOpacity
onPress={() => {
if (answers[qtn.QuestionId]) {
setSelectedImg(answers[qtn.QuestionId]);
setReCapImgModalObj({ cameraType: '1' });
setActiveCameraQId(qtn.QuestionId);
setShowModal(true);
} else {
openCamera(qtn.QuestionId); // if no image yet, open camera directly
}
}}
>
<Image
source={answers[qtn.QuestionId] ? IMAGES.greenCameraIcon : IMAGES.redCameraIcon}
style={{ width: 40, height: 40 }}
/>
</TouchableOpacity>
</>
)}
</View>
);
})}
</View>
</View>
</ScrollView>
<CustomButton
onPress={saveAnswers}
title={'Save'}
style={styles.btnbg}
textstyle={styles.btntext}
/>
{showCamera && (
<Modal visible={showCamera} animationType="slide" presentationStyle="fullScreen">
<CustomCamera
onImageCaptured={handleImageCaptured}
onClose={() => setShowCamera(false)}
/>
</Modal>
)}
{/* Modal Preview with Retake */}
{_OpenCaptureImage_Modal(selectedImg)}
</SafeAreaView>
</KeyboardAwareScrollView>
);
};
export default FeedbackFormScreen;