ui fix
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
// src/components/CustomAlert.tsx
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
Modal,
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
} from "react-native";
|
||||
import { BlurView } from "@react-native-community/blur";
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
import colors from "./colors"; // Import centralized colors
|
||||
|
||||
interface AlertButton {
|
||||
text: string;
|
||||
onPress: () => void;
|
||||
style?: "cancel" | "destructive" | "default";
|
||||
}
|
||||
|
||||
interface CustomAlertProps {
|
||||
visible: boolean;
|
||||
title: string;
|
||||
message: string;
|
||||
buttons: AlertButton[];
|
||||
alertType?: 'error' | 'success' | 'info';
|
||||
}
|
||||
|
||||
const CustomAlert: React.FC<CustomAlertProps> = ({
|
||||
visible,
|
||||
title,
|
||||
message,
|
||||
buttons,
|
||||
alertType = 'info',
|
||||
}) => {
|
||||
|
||||
const getIcon = () => {
|
||||
switch (alertType) {
|
||||
case 'error':
|
||||
return { name: "close-circle", color: colors.error };
|
||||
case 'success':
|
||||
return { name: "checkmark-circle", color: colors.success };
|
||||
default:
|
||||
return { name: "information-circle", color: colors.primary };
|
||||
}
|
||||
};
|
||||
|
||||
const icon = getIcon();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={visible}
|
||||
onRequestClose={() => {
|
||||
const closeButton = buttons.find(b => b.style === 'cancel') || buttons[0];
|
||||
closeButton?.onPress();
|
||||
}}
|
||||
>
|
||||
<View style={styles.centeredView}>
|
||||
{Platform.OS === 'ios' ? (
|
||||
<BlurView style={styles.absolute} blurType="light" blurAmount={5} />
|
||||
) : (
|
||||
<View style={[styles.absolute, { backgroundColor: colors.androidBackdrop }]} />
|
||||
)}
|
||||
|
||||
<View style={styles.alertBox}>
|
||||
<View style={styles.iconContainer}>
|
||||
<Ionicons name={icon.name} size={48} color={icon.color} />
|
||||
</View>
|
||||
<Text style={styles.alertTitle}>{title}</Text>
|
||||
<Text style={styles.alertMessage}>{message}</Text>
|
||||
|
||||
<View style={styles.buttonContainer}>
|
||||
{buttons.map((button, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[
|
||||
styles.button,
|
||||
button.style === 'destructive' ? styles.destructiveButton : styles.defaultButton,
|
||||
]}
|
||||
onPress={button.onPress}
|
||||
>
|
||||
<Text style={[
|
||||
styles.buttonText,
|
||||
button.style === 'destructive' ? styles.destructiveButtonText : styles.defaultButtonText
|
||||
]}>
|
||||
{button.text}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
centeredView: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
absolute: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
},
|
||||
alertBox: {
|
||||
backgroundColor: colors.alertBackground,
|
||||
borderRadius: 24,
|
||||
padding: 24,
|
||||
alignItems: "center",
|
||||
margin: 24,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(255, 255, 255, 0.5)',
|
||||
shadowColor: colors.black,
|
||||
shadowOffset: { width: 0, height: 10 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 30,
|
||||
elevation: 20,
|
||||
width: '90%',
|
||||
maxWidth: 400,
|
||||
},
|
||||
iconContainer: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
alertTitle: {
|
||||
fontSize: 22,
|
||||
fontWeight: "bold",
|
||||
color: colors.textDark,
|
||||
marginBottom: 8,
|
||||
textAlign: "center",
|
||||
},
|
||||
alertMessage: {
|
||||
fontSize: 16,
|
||||
color: colors.textLight,
|
||||
textAlign: "center",
|
||||
marginBottom: 24,
|
||||
lineHeight: 22,
|
||||
},
|
||||
buttonContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: 'flex-end',
|
||||
width: "100%",
|
||||
gap: 12,
|
||||
},
|
||||
button: {
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: 24,
|
||||
borderRadius: 16,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
defaultButton: {
|
||||
backgroundColor: colors.primary,
|
||||
},
|
||||
destructiveButton: {
|
||||
backgroundColor: colors.error,
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "700",
|
||||
},
|
||||
defaultButtonText: {
|
||||
color: colors.white,
|
||||
},
|
||||
destructiveButtonText: {
|
||||
color: colors.white,
|
||||
},
|
||||
});
|
||||
|
||||
export default CustomAlert;
|
||||
+20
-15
@@ -1,22 +1,27 @@
|
||||
// colors.ts
|
||||
const colors = {
|
||||
pastelPink: "#decbfcff", // darker pink
|
||||
pastelBlue: "#D7E9F7", // darker blue
|
||||
pastelGreen: "#DFF6DD", // darker green
|
||||
pastelOrange: "#FFF4D2", // darker orange
|
||||
// src/components/colors.ts
|
||||
|
||||
// darker accent colors
|
||||
Home: "#995dfaff", // Rose red for contrast
|
||||
Profile: "#2D9CDB", // Deep sky blue
|
||||
Group: "#27AE60", // Green for freshness
|
||||
Settings: "#F39C12", // Amber for warmth
|
||||
const colors = {
|
||||
// Pastel palette
|
||||
pastelPink: "#decbfc",
|
||||
pastelBlue: "#D7E9F7",
|
||||
pastelGreen: "#DFF6DD",
|
||||
pastelOrange: "#FFF4D2",
|
||||
|
||||
// common text + UI colors
|
||||
textDark: "#212121",
|
||||
textLight: "#555555",
|
||||
// Primary and status colors
|
||||
primary: "#711ff7",
|
||||
error: "#EF4444",
|
||||
success: "#22C55E",
|
||||
|
||||
// Common UI colors
|
||||
textDark: "#1F2937",
|
||||
textLight: "#6B7280",
|
||||
white: "#FFFFFF",
|
||||
black: "#000000",
|
||||
primary: "#711ff7ff",
|
||||
inputBorder: "#E5E7EB",
|
||||
|
||||
// Special background colors with transparency
|
||||
alertBackground: "rgba(255, 255, 255, 0.8)",
|
||||
androidBackdrop: "rgba(0, 0, 0, 0.4)",
|
||||
};
|
||||
|
||||
export default colors;
|
||||
|
||||
@@ -5,10 +5,12 @@ import {
|
||||
StyleSheet,
|
||||
TouchableWithoutFeedback,
|
||||
Animated,
|
||||
ViewStyle,
|
||||
} from "react-native";
|
||||
import LinearGradient from "react-native-linear-gradient";
|
||||
import { Ionicons, IoniconsIconName } from "@react-native-vector-icons/ionicons";
|
||||
import colors from "../colors";
|
||||
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||
import { IoniconsIconName } from "react-native-vector-icons/Ionicons";
|
||||
import colors from "../colors"; // Assuming your pastel colors are defined here
|
||||
|
||||
type CardProps = {
|
||||
title: string;
|
||||
@@ -16,7 +18,8 @@ type CardProps = {
|
||||
iconName?: IoniconsIconName;
|
||||
onPress?: () => void;
|
||||
backOne?: string;
|
||||
backTwo?: string
|
||||
backTwo?: string;
|
||||
style?: ViewStyle;
|
||||
};
|
||||
|
||||
const AnimatedCard: React.FC<CardProps> = ({
|
||||
@@ -24,33 +27,27 @@ const AnimatedCard: React.FC<CardProps> = ({
|
||||
subtitle,
|
||||
iconName = "ellipse",
|
||||
onPress,
|
||||
backOne = '#4facfe',
|
||||
backTwo = '#00f2fe'
|
||||
backOne = colors.pastelPink, // Defaulting to pastelPink
|
||||
backTwo = colors.primary,
|
||||
style,
|
||||
}) => {
|
||||
const scale = useRef(new Animated.Value(1)).current;
|
||||
|
||||
const handlePressIn = () => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 0.96,
|
||||
useNativeDriver: true,
|
||||
friction: 4,
|
||||
}).start();
|
||||
Animated.spring(scale, { toValue: 0.96, useNativeDriver: true, friction: 4 }).start();
|
||||
};
|
||||
|
||||
const handlePressOut = () => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 1,
|
||||
useNativeDriver: true,
|
||||
friction: 4,
|
||||
}).start(() => onPress && onPress());
|
||||
Animated.spring(scale, { toValue: 1, useNativeDriver: true, friction: 4 }).start(() => {
|
||||
if (onPress) {
|
||||
onPress();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
onPressIn={handlePressIn}
|
||||
onPressOut={handlePressOut}
|
||||
>
|
||||
<Animated.View style={[styles.card, { transform: [{ scale }] }]}>
|
||||
<TouchableWithoutFeedback onPressIn={handlePressIn} onPressOut={handlePressOut}>
|
||||
<Animated.View style={[styles.card, style, { transform: [{ scale }] }]}>
|
||||
<LinearGradient
|
||||
colors={[backOne, backTwo]}
|
||||
start={{ x: 0, y: 0 }}
|
||||
@@ -59,21 +56,11 @@ const AnimatedCard: React.FC<CardProps> = ({
|
||||
>
|
||||
{/* Decorative Graphics */}
|
||||
<View style={styles.graphicCircleLarge} />
|
||||
<View style={styles.graphicCircleMedium} />
|
||||
<View style={styles.graphicCircleSmall} />
|
||||
<View style={styles.graphicTriangleTop} />
|
||||
<View style={styles.graphicTriangleBottom} />
|
||||
|
||||
{/* Content */}
|
||||
<View style={styles.content}>
|
||||
{iconName && (
|
||||
<Ionicons
|
||||
name={iconName}
|
||||
size={32}
|
||||
color="#fff"
|
||||
style={styles.icon}
|
||||
/>
|
||||
)}
|
||||
{iconName && <Ionicons name={iconName} size={38} color="#fff" style={styles.icon} />}
|
||||
<View style={styles.textContainer}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
|
||||
@@ -87,102 +74,70 @@ const AnimatedCard: React.FC<CardProps> = ({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
// marginHorizontal: 16,
|
||||
marginVertical: 10,
|
||||
borderRadius: 20,
|
||||
borderRadius: 24,
|
||||
overflow: "hidden",
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 8,
|
||||
elevation: 8,
|
||||
shadowOffset: { width: 0, height: 5 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 12,
|
||||
elevation: 5,
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
gradient: {
|
||||
minHeight: 120,
|
||||
minHeight: 150, // Increased height for better spacing
|
||||
position: "relative",
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
// Graphics
|
||||
graphicCircleLarge: {
|
||||
position: "absolute",
|
||||
top: -20,
|
||||
right: -20,
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 40,
|
||||
backgroundColor: "rgba(124, 80, 80, 0.42)",
|
||||
},
|
||||
graphicCircleMedium: {
|
||||
position: "absolute",
|
||||
bottom: 30,
|
||||
left: -15,
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
backgroundColor: "rgba(122, 41, 41, 0.39)",
|
||||
top: -30,
|
||||
right: -40,
|
||||
width: 100,
|
||||
height: 100,
|
||||
borderRadius: 50,
|
||||
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
||||
},
|
||||
graphicCircleSmall: {
|
||||
position: "absolute",
|
||||
bottom: -10,
|
||||
right: 40,
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "rgba(207, 110, 80, 0.25)",
|
||||
},
|
||||
graphicTriangleTop: {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderStyle: "solid",
|
||||
borderRightWidth: 60,
|
||||
borderTopWidth: 60,
|
||||
borderRightColor: "transparent",
|
||||
borderTopColor: "rgba(143, 62, 62, 0.31)",
|
||||
},
|
||||
graphicTriangleBottom: {
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
borderStyle: "solid",
|
||||
borderLeftWidth: 40,
|
||||
borderBottomWidth: 40,
|
||||
borderLeftColor: "transparent",
|
||||
borderBottomColor: "rgba(172, 51, 51, 0.27)",
|
||||
bottom: -20,
|
||||
left: -25,
|
||||
width: 70,
|
||||
height: 70,
|
||||
borderRadius: 35,
|
||||
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
||||
},
|
||||
content: {
|
||||
flexDirection: "row", // stack vertically
|
||||
alignItems: "center", // center horizontally
|
||||
justifyContent: "center", // center vertically
|
||||
padding: 20,
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
alignSelf: "center",
|
||||
flex:1
|
||||
}
|
||||
,
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
icon: {
|
||||
marginRight: 12,
|
||||
marginBottom: 12,
|
||||
},
|
||||
textContainer: {
|
||||
// alignItems: "center", // centers title and subtitle
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: "700",
|
||||
fontWeight: "bold",
|
||||
color: "#fff",
|
||||
marginBottom: 4,
|
||||
textTransform:'uppercase'
|
||||
// textAlign: "center",
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 1,
|
||||
textAlign: 'center',
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 14,
|
||||
color: colors.primary,
|
||||
fontSize: 13,
|
||||
color: colors.white,
|
||||
opacity: 0.9,
|
||||
fontWeight: "500",
|
||||
textAlign: "center",
|
||||
marginTop: 4,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -15,10 +15,12 @@ type CustomInputProps = TextInputProps & {
|
||||
label?: string;
|
||||
icon?: IoniconsIconName;
|
||||
error?:string
|
||||
value?: string | number;
|
||||
};
|
||||
|
||||
const CustomInput: React.FC<CustomInputProps> = ({
|
||||
label,
|
||||
value,
|
||||
icon,
|
||||
style,
|
||||
error,
|
||||
@@ -28,7 +30,7 @@ const CustomInput: React.FC<CustomInputProps> = ({
|
||||
<View style={styles.inputContainer}>
|
||||
{label ? <Text style={styles.inputLabel}>{label}</Text> : null}
|
||||
<View style={styles.inputWrapper}>
|
||||
{icon && <Ionicons name={icon} size={20} color={colors.textDark} style={styles.inputIcon} />}
|
||||
{icon && <Ionicons name={icon} size={20} color={colors.pastelBlue} style={styles.inputIcon} />}
|
||||
<TextInput
|
||||
style={[styles.input, icon && { paddingLeft: 36 }, style]}
|
||||
placeholderTextColor={colors.textLight}
|
||||
@@ -83,7 +85,7 @@ const CustomButton: React.FC<CustomButtonProps> = ({
|
||||
|
||||
// --- Styles ---
|
||||
const styles = StyleSheet.create({
|
||||
inputContainer: { marginBottom: 12 },
|
||||
inputContainer: { marginBottom: 12,elevation:5 },
|
||||
inputLabel: { fontSize: 14, fontWeight: "500", color: colors.textDark, marginBottom: 6 },
|
||||
inputWrapper: {
|
||||
flexDirection: "row",
|
||||
@@ -97,9 +99,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
input: {
|
||||
flex: 1,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.textLight,
|
||||
borderRadius: 10,
|
||||
borderRadius: 15,
|
||||
padding: 12,
|
||||
paddingLeft: 12,
|
||||
backgroundColor: colors.white,
|
||||
@@ -107,6 +107,7 @@ const styles = StyleSheet.create({
|
||||
fontSize: 15,
|
||||
},
|
||||
button: {
|
||||
elevation:5,
|
||||
paddingVertical: 12,
|
||||
borderRadius: 12,
|
||||
alignItems: "center",
|
||||
|
||||
Reference in New Issue
Block a user