common component

This commit is contained in:
Jaanu423
2025-09-15 12:12:48 +05:30
17 changed files with 1224 additions and 427 deletions
+37
View File
@@ -0,0 +1,37 @@
import React from "react";
import { StatusBar, StyleSheet, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
type AppViewProps = {
children: React.ReactNode;
backgroundColor?: string;
barStyle?: "default" | "light-content" | "dark-content";
};
export default function AppView({
children,
backgroundColor = "#f5f5f5",
barStyle = "dark-content",
}: AppViewProps) {
return (
<SafeAreaView style={[styles.safeArea, { backgroundColor }]}>
<StatusBar
translucent={false}
backgroundColor={backgroundColor}
barStyle={barStyle}
/>
<View style={styles.container}>{children}</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
},
container: {
flex: 1,
paddingHorizontal: 16,
paddingTop: 8,
},
});
+50
View File
@@ -0,0 +1,50 @@
import React from "react";
import { TouchableOpacity, Text, StyleSheet, ActivityIndicator, ViewStyle } from "react-native";
type CustomButtonProps = {
title: string;
onPress: () => void;
backgroundColor?: string;
textColor?: string;
loading?: boolean;
style?: ViewStyle;
};
export default function CustomButton({
title,
onPress,
backgroundColor = "#6C63FF",
textColor = "#fff",
loading = false,
style,
}: CustomButtonProps) {
return (
<TouchableOpacity
style={[styles.button, { backgroundColor }, style]}
onPress={onPress}
disabled={loading}
activeOpacity={0.8}
>
{loading ? (
<ActivityIndicator color={textColor} />
) : (
<Text style={[styles.text, { color: textColor }]}>{title}</Text>
)}
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
button: {
paddingVertical: 16,
paddingHorizontal: 20,
borderRadius: 12,
alignItems: "center",
justifyContent: "center",
marginVertical: 5,
},
text: {
fontSize: 16,
fontWeight: "bold",
},
});
+175
View File
@@ -0,0 +1,175 @@
import React from "react";
import {
StyleSheet,
View,
Text,
TextInput,
TouchableOpacity,
} from "react-native";
import { TextInputProps } from "react-native";
import {Ionicons} from "@react-native-vector-icons/ionicons";
type CustomInputProps = TextInputProps & {
label: string;
value: string;
placeholder: string;
onChangeText: (text: string) => void;
icon?: string;
};
const CustomInput: React.FC<CustomInputProps> = ({
label,
value,
placeholder,
onChangeText,
icon,
...rest
}) => (
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>{label}</Text>
<View style={styles.inputWrapper}>
{icon && <Ionicons name={icon} size={20} color="#555" style={styles.inputIcon} />}
<TextInput
style={[styles.input, icon && { paddingLeft: 36 }]}
placeholder={placeholder}
value={value}
placeholderTextColor="#999"
onChangeText={onChangeText}
{...rest}
/>
</View>
</View>
);
type CustomButtonProps = {
title: string;
onPress: () => void;
type?: "primary" | "secondary" | "danger" | "outline";
icon?: string | null;
style?: object;
};
const CustomButton: React.FC<CustomButtonProps> = ({
title,
onPress,
type = "primary",
icon,
}) => (
<TouchableOpacity
style={[
styles.button,
type === "secondary" && styles.buttonSecondary,
type === "danger" && styles.buttonDanger,
]}
onPress={onPress}
activeOpacity={0.8}
>
<View style={styles.buttonContent}>
{icon && <Ionicons name={icon || 'user'} size={20} color={type === "secondary" ? "#333" : "#fff"} style={{ marginRight: 8 }} />}
<Text
style={[
styles.buttonText,
type === "secondary" && styles.buttonTextSecondary,
type === "danger" && styles.buttonTextDanger,
]}
>
{title}
</Text>
</View>
</TouchableOpacity>
);
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: "#f5f7fb" },
loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center" },
loadingText: { marginTop: 10, fontSize: 16, color: "#007AFF" },
header: {
flexDirection: "row",
justifyContent: "space-between",
padding: 16,
paddingTop: 40,
backgroundColor: "#fff",
alignItems: "center",
borderBottomWidth: 1,
borderColor: "#eee",
},
headerTitle: { fontSize: 20, fontWeight: "600", color: "#333" },
profileCard: {
borderRadius: 16,
margin: 16,
backgroundColor: "#fff",
padding: 20,
shadowColor: "#000",
shadowOpacity: 0.1,
shadowRadius: 6,
elevation: 4,
},
profileHeader: { alignItems: "center", marginBottom: 16 },
avatar: { width: 100, height: 100, borderRadius: 50, marginBottom: 8 },
cameraIcon: {
position: "absolute",
right: 110,
bottom: 10,
backgroundColor: "#007AFF",
borderRadius: 15,
width: 32,
height: 32,
justifyContent: "center",
alignItems: "center",
},
detail: {
fontSize: 16,
marginBottom: 10,
color: "#444",
paddingLeft: 4,
},
inputContainer: { marginBottom: 12 },
inputLabel: { fontSize: 14, fontWeight: "500", color: "#555", marginBottom: 6 },
inputWrapper: {
flexDirection: "row",
alignItems: "center",
position: "relative",
},
inputIcon: {
position: "absolute",
left: 10,
zIndex: 1,
},
input: {
flex: 1,
borderWidth: 1,
borderColor: "#ddd",
borderRadius: 10,
padding: 12,
paddingLeft: 12,
backgroundColor: "#fdfdfd",
color: "#000",
fontSize: 15,
},
button: {
backgroundColor: "#007AFF",
paddingVertical: 12,
borderRadius: 12,
alignItems: "center",
marginVertical: 6,
shadowColor: "#007AFF",
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 3,
},
buttonSecondary: {
backgroundColor: "#e5e5ea",
},
buttonDanger: {
backgroundColor: "#ff3b30",
},
buttonContent: {
flexDirection: "row",
alignItems: "center",
},
buttonText: { color: "#fff", fontSize: 16, fontWeight: "600" },
buttonTextSecondary: { color: "#333" },
buttonTextDanger: { color: "#fff" },
});
export { CustomInput, styles, CustomButton };