store dna all done

This commit is contained in:
CPM
2025-07-30 10:35:06 +05:30
commit b0399b39c6
157 changed files with 35444 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
import React from 'react';
import {
Alert,
View,
TouchableOpacity,
Text,
} from 'react-native';
import CustomModal from './CustomModal';
import { useRoute } from '@react-navigation/native';
import { GlobalTheme } from '../theme';
export const CustomAlert = (
title = '',
msg = '',
onCancel = () => { },
onDone = () => { }
) => {
Alert.alert(title, msg, [
{
text: 'Cancel',
onPress: onCancel,
style: 'cancel',
},
{ text: 'OK', onPress: onDone },
]);
};
export function ConfirmSaveAlert({
showAlert = false,
onCancelCallBack = () => { },
onYesCallBack = () => { },
msg = 'Do you really want to save data?',
yesText = 'Yes',
cancelText = 'NO',
}) {
return (
<CustomModal
title={msg}
showModal={showAlert}
onClose={onCancelCallBack} // 👈 ensures modal closes when tapping close icon
>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 20, width: '60%' }}>
<TouchableOpacity
style={{
paddingHorizontal: 25,
paddingVertical: 10,
backgroundColor: GlobalTheme.colors.primary,
borderRadius: 5,
}}
onPress={onYesCallBack}
>
<Text style={{
color: '#FFF',
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.medium
}}>
{yesText}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
paddingHorizontal: 25,
paddingVertical: 10,
backgroundColor: '#ccc',
borderRadius: 5,
}}
onPress={onCancelCallBack}
>
<Text style={{
color: '#000',
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.medium
}}>
{cancelText}
</Text>
</TouchableOpacity>
</View>
</CustomModal>
);
}
export function ExitScreenAlert(props, callback) {
Alert.alert(
'',
'Do you really want to exit the screen?',
[
{
text: 'Cancel',
onPress: () => { },
style: 'cancel',
},
{
text: 'OK',
onPress: () => {
if (typeof callback === 'function') callback();
props.navigation.goBack();
},
},
]
);
}
+33
View File
@@ -0,0 +1,33 @@
// src/components/Background.js
import React from 'react';
import { StyleSheet, StatusBar, useColorScheme } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../theme';
const Background = ({ children, barcolor = 'light-content'}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={'light-content'} />
<LinearGradient colors={['#E3EBF8', '#ffffff']} start={{ x: 0.5, y: 0 }} end={{ x: 0.5, y: 1 }} style={styles.gradient}>
{children}
</LinearGradient>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
gradient: {
flex: 1,
// paddingHorizontal: 20,
},
});
export default Background;
+51
View File
@@ -0,0 +1,51 @@
import React, { useState } from 'react';
import { View, TouchableOpacity, Image, StyleSheet, Modal } from 'react-native';
import IMAGES from '../constants/Images';
import CustomCamera from './CustomCamera';
const CameraScreen = () => {
const [showCamera, setShowCamera] = useState(false);
const [imageUri, setImageUri] = useState(null);
const handleImageCaptured = (photo) => {
setImageUri(photo.uri);
setShowCamera(false);
};
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => setShowCamera(true)}>
<Image
source={imageUri ? { uri: imageUri } : IMAGES.cameraIcon}
style={styles.imagePreview}
/>
</TouchableOpacity>
{/* Fullscreen Modal Camera */}
<Modal visible={showCamera} animationType="slide" presentationStyle="fullScreen">
<CustomCamera
onImageCaptured={handleImageCaptured}
onClose={() => setShowCamera(false)}
/>
</Modal>
</View>
);
};
export default CameraScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
imagePreview: {
width: 150,
height: 150,
borderRadius: 10,
borderWidth: 1,
borderColor: '#ccc',
},
});
+103
View File
@@ -0,0 +1,103 @@
import React from "react";
import {
View,
Text,
TouchableOpacity,
Modal,
StyleSheet,
} from "react-native";
import { GlobalTheme } from "../theme";
const CustomAlertModal = ({
showModal,
title,
message,
buttons = [],
style = {},
titleStyle = {},
messageStyle = {},
children,
}) => {
return (
<Modal
visible={showModal}
transparent
animationType="fade"
>
<View style={styles.backdrop}>
<View style={[styles.modalContainer, style]}>
<TouchableOpacity onPress={onClose} style={styles.closeIcon}>
<Text style={{ fontSize: 18 }}></Text>
</TouchableOpacity>
{title ? (
<Text style={[styles.title, titleStyle]}>{title}</Text>
) : null}
{message ? (
<Text style={[styles.message, messageStyle]}>{message}</Text>
) : null}
{children}
<View style={styles.buttonRow}>
{buttons.map((btn, index) => (
<TouchableOpacity
key={index}
style={[styles.button, { backgroundColor: btn.backgroundColor || GlobalTheme.colors.primary }]}
onPress={btn.onPress}
>
<Text style={[styles.buttonText, { color: btn.color || "#FFF" }]}>
{btn.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</View>
</Modal>
);
};
export default CustomAlertModal;
const styles = StyleSheet.create({
backdrop: {
flex: 1,
backgroundColor: "rgba(0,0,0,0.5)",
justifyContent: "center",
alignItems: "center",
},
modalContainer: {
width: "80%",
backgroundColor: "#fff",
borderRadius: 10,
padding: 20,
elevation: 5,
},
title: {
fontSize: 18,
fontWeight: "bold",
marginBottom: 10,
textAlign: "center",
},
message: {
fontSize: 16,
marginBottom: 20,
textAlign: "center",
},
buttonRow: {
flexDirection: "row",
justifyContent: "flex-end",
marginTop: 10,
},
button: {
paddingHorizontal: 15,
paddingVertical: 8,
borderRadius: 5,
marginLeft: 10,
},
buttonText: {
fontSize: 14,
},
});
+13
View File
@@ -0,0 +1,13 @@
import { View, Text, TouchableOpacity } from 'react-native';
const CustomButton = ({ title, style, textstyle, onPress , disabled}) => {
return (
<TouchableOpacity disabled={disabled} onPress={onPress}>
<View style={{ marginHorizontal: 0, paddingVertical: 10, ...style }}>
<Text style={{ textAlign: 'center', ...textstyle }}>{title}</Text>
</View>
</TouchableOpacity>
);
};
export default CustomButton;
+173
View File
@@ -0,0 +1,173 @@
import React, { useState, useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, Image, StyleSheet, PermissionsAndroid, Platform } from 'react-native';
import { Camera, useCameraDevice } from 'react-native-vision-camera';
import { useIsFocused } from '@react-navigation/native';
const CustomCamera = ({ onImageCaptured, onClose }) => {
const cameraRef = useRef(null);
const [hasPermission, setHasPermission] = useState(false);
const [cameraPosition, setCameraPosition] = useState('back');
const [capturedPhoto, setCapturedPhoto] = useState(null);
const isFocused = useIsFocused();
const device = useCameraDevice(cameraPosition);
useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission();
console.log(status, "Camera permission status");
setHasPermission(status === 'granted');
})();
}, []);
const takePhoto = async () => {
if (cameraRef.current) {
try {
const photo = await cameraRef.current.takePhoto({
flash: 'off',
});
const photoUri = Platform.OS === 'android' ? `file://${photo.path}` : photo.path;
setCapturedPhoto(photoUri);
} catch (error) {
console.warn('Error taking photo:', error);
}
}
};
const flipCamera = () => {
setCameraPosition(prev => (prev === 'back' ? 'front' : 'back'));
};
const confirmPhoto = async () => {
if (onImageCaptured && capturedPhoto) {
try {
const imageInfo = await new Promise((resolve, reject) => {
Image.getSize(
capturedPhoto,
(width, height) => resolve({ width, height }),
(error) => reject(error)
);
});
const normalizedUri = Platform.OS === 'android' ? capturedPhoto : `file://${capturedPhoto}`;
onImageCaptured({
uri: normalizedUri,
width: imageInfo.width,
height: imageInfo.height,
storeData: {},
});
} catch (e) {
console.warn('Failed to get image size:', e);
onImageCaptured({
uri: capturedPhoto,
width: 0,
height: 0,
storeData: {},
});
}
}
};
const retakePhoto = () => {
setCapturedPhoto(null);
};
if (!device || !hasPermission) {
return (
<View style={styles.centered}>
<Text>Loading Camera...</Text>
</View>
);
}
return (
<View style={styles.container}>
{capturedPhoto ? (
<View style={styles.previewContainer}>
<Image source={{ uri: capturedPhoto }} style={styles.preview} resizeMode="contain" />
<View style={styles.buttonRow}>
<TouchableOpacity onPress={retakePhoto} style={styles.button}>
<Text>Retake</Text>
</TouchableOpacity>
<TouchableOpacity onPress={confirmPhoto} style={styles.button}>
<Text>Use Photo</Text>
</TouchableOpacity>
</View>
</View>
) : (
<>
{isFocused && !capturedPhoto && (
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
photo={true}
ref={cameraRef}
/>
)}
<View style={styles.controls}>
<TouchableOpacity onPress={flipCamera} style={styles.button}>
<Text>Flip</Text>
</TouchableOpacity>
<TouchableOpacity onPress={takePhoto} style={styles.captureButton} />
<TouchableOpacity onPress={onClose} style={styles.button}>
<Text>Close</Text>
</TouchableOpacity>
</View>
</>
)}
</View>
);
};
export default CustomCamera;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
height: '100%',
},
previewContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
height: '100%',
},
preview: {
width: '100%',
height: '80%',
},
controls: {
position: 'absolute',
bottom: 30,
width: '100%',
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
captureButton: {
width: 70,
height: 70,
borderRadius: 35,
backgroundColor: 'white',
borderWidth: 5,
borderColor: 'gray',
},
button: {
backgroundColor: 'white',
padding: 10,
borderRadius: 8,
},
buttonRow: {
flexDirection: 'row',
justifyContent: 'space-around',
marginTop: 20,
width: '100%',
},
centered: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
+41
View File
@@ -0,0 +1,41 @@
// src/components/CustomDropdown.js
import React from 'react';
import { StyleSheet } from 'react-native';
import { Dropdown } from 'react-native-element-dropdown';
const CustomDropdown = ({
data = [],
value,
onChange,
placeholder = '--Select--',
containerStyle = {},
}) => {
return (
<Dropdown
style={[styles.dropdown, containerStyle]}
data={data}
labelField="label"
valueField="value"
placeholder={placeholder}
placeholderStyle={{ fontSize: 13, fontWeight: '500', color: 'gray' }}
value={value}
selectedTextStyle={{fontSize: 13, fontWeight: '500', color: '#000'}}
itemTextStyle={{fontSize:13,color:'#000'}}
onChange={onChange}
/>
);
};
const styles = StyleSheet.create({
dropdown: {
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
paddingHorizontal: 10,
height: 45,
marginBottom: 0, // ✅ no margin
paddingBottom: 0, // ✅ no padding
},
});
export default CustomDropdown;
+73
View File
@@ -0,0 +1,73 @@
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native'
import React from 'react'
import { GlobalTheme } from '../theme'
const CustomHeader = ({ title, leftIcon, rightIcon, onLeftPress, onRightPress }) => {
return (
<View style={styles.headerStyle}>
{leftIcon &&
<TouchableOpacity onPress={onLeftPress} style={styles.leftSection}>
{leftIcon && <Image source={leftIcon} style={styles.leftIconStyle} />}
</TouchableOpacity>
}
<View style={styles.titleContainer}>
<Text style={styles.headerText}>{title}</Text>
</View>
<TouchableOpacity onPress={onRightPress} style={styles.rightSection}>
{rightIcon && <Image source={rightIcon} style={styles.rightIconStyle} />}
</TouchableOpacity>
</View>
)
}
export default CustomHeader
const styles = StyleSheet.create({
headerStyle: {
height: '8%',
backgroundColor: '#113F8C',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 15,
},
leftSection: {
backgroundColor: '#295398',
flexDirection: 'row',
padding: 8,
alignItems: 'center',
borderRadius: 20
// width: 70,
},
rightSection: {
alignItems: 'flex-end',
width: 40,
},
titleContainer: {
flex: 1,
alignItems: 'center',
},
headerText: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.medium,
fontWeight: '600',
},
backText: {
marginLeft: 6,
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.small,
},
leftIconStyle: {
height: 20,
width: 20,
resizeMode: 'contain',
},
rightIconStyle: {
height: 35,
width: 35,
resizeMode: 'contain',
},
})
+79
View File
@@ -0,0 +1,79 @@
import React from 'react';
import { View, Text, Modal, StyleSheet, TouchableOpacity, Image} from 'react-native';
import IMAGES from '../constants/Images';
const CustomModal = ({
showModal,
title,
message,
children,
// onClose,
style = {},
titleStyle = {},
messageStyle = {},
hideDefaultClose = false, // 🔥 new prop
onClose = null
}) => {
return (
<Modal visible={showModal} transparent animationType="fade">
<View style={styles.overlay}>
<View style={[styles.modalContainer, style]}>
{onClose && (
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
<Image source={IMAGES.crossIcon} style={styles.iconStyle} />
</TouchableOpacity>
)}
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
{message && <Text style={[styles.message, messageStyle]}>{message}</Text>}
<View style={{ marginVertical: 10 }}>{children}</View>
</View>
</View>
</Modal>
);
};
export default CustomModal;
const styles = StyleSheet.create({
overlay: {
flex: 1,
backgroundColor: '#00000088',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
width: '90%',
backgroundColor: '#fff',
borderRadius: 12,
padding: 15,
alignItems: 'center',
minHeight:200
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 6,
},
message: {
fontSize: 14,
color: '#555',
textAlign: 'center',
},
closeButton: {
alignSelf:'flex-end',
marginBottom:15
},
closeText: {
color: '#fff',
fontWeight: 'bold',
},
iconStyle:{
height:35,
width:35,
resizeMode:'contain',
// tintColor:'red'
}
});
+85
View File
@@ -0,0 +1,85 @@
import { View, Text, TextInput, StyleSheet, } from 'react-native';
import React, { useState } from 'react';
import { GlobalTheme, Screen } from '../theme';
const CustomTextInput = ({
label,
value,
onChangeText,
keyboardType,
secureTextEntry,
right,
textstyle,
viewstyle,
maxLength
}) => {
const [isFocused, setFocused] = useState(false);
const [hidepassword, setHidePassword] = useState(false);
const handleFocus = () => {
setFocused(true);
};
const handleBlur = () => {
setFocused(false);
};
const inputStyle = {
borderColor: isFocused ? '#2680EB' : '#DFDFDF',
borderWidth: isFocused ? 2 : 1,
backgroundColor: isFocused ? '#FFF' : '#Fff',
borderRadius: GlobalTheme.borderRadius.md,
};
return (
<View style={styles.inputContainer}>
<Text
style={{
color: GlobalTheme.colors.black,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
marginTop: 10,
marginHorizontal: 0,
...textstyle,
}}>
{label}
</Text>
<View
style={{
borderRadius: GlobalTheme.borderRadius.lgg,
// borderWidth: 6,
borderColor: isFocused ? '#DFECFF' : 'transparent',
marginTop: 8,
...viewstyle,
}}>
<TextInput
maxLength={maxLength}
style={[styles.input, inputStyle]}
value={value}
onChangeText={onChangeText}
keyboardType={keyboardType}
autoCapitalize="none"
onFocus={handleFocus}
onBlur={handleBlur}
placeholder={`Enter your ${label.toLowerCase()}`}
placeholderTextColor={'#555555'}
/>
</View>
</View>
);
};
export default CustomTextInput;
const styles = StyleSheet.create({
input: {
height: 50,
borderWidth: 1,
padding: 10,
color: GlobalTheme.colors.black,
},
inputContainer: {
marginBottom: 16,
},
});