theme
This commit is contained in:
+87
-74
@@ -19,17 +19,27 @@ import type { StackNavigationProp } from '@react-navigation/stack';
|
||||
import { RootStackParamList } from '../navigation/AppNavigator';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
import MaterialRipple from 'react-native-material-ripple';
|
||||
import MaterialRipple from 'react-native-material-ripple';
|
||||
import CustomAlert from '../components/CostomAlart';
|
||||
import colors from '../components/colors';
|
||||
import { responsiveFontSize } from 'react-native-responsive-dimensions';
|
||||
import {
|
||||
responsiveHeight,
|
||||
responsiveWidth,
|
||||
responsiveFontSize
|
||||
} from "react-native-responsive-dimensions";
|
||||
import { useTheme } from '../theme/ThemeProvider';
|
||||
import FontsFamily from '../constents/FontsFamily';
|
||||
|
||||
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const BLOCK_SIZE = width / 3;
|
||||
|
||||
|
||||
// Note: You will need to install react-native-material-ripple
|
||||
// npm install react-native-material-ripple
|
||||
|
||||
|
||||
export default function LoginScreen() {
|
||||
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
|
||||
const [mobile, setMobile] = useState('');
|
||||
@@ -42,9 +52,12 @@ export default function LoginScreen() {
|
||||
alertType: 'info' as 'info' | 'success' | 'error',
|
||||
});
|
||||
|
||||
|
||||
const fade = useRef(new Animated.Value(0)).current;
|
||||
const slide = useRef(new Animated.Value(30)).current;
|
||||
const ctaScale = useRef(new Animated.Value(1)).current;
|
||||
const { theme } = useTheme();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
Animated.parallel([
|
||||
@@ -53,6 +66,7 @@ export default function LoginScreen() {
|
||||
]).start();
|
||||
}, []);
|
||||
|
||||
|
||||
const showAlert = (
|
||||
title: string,
|
||||
message: string,
|
||||
@@ -62,10 +76,12 @@ export default function LoginScreen() {
|
||||
setAlertInfo({ visible: true, title, message, buttons, alertType });
|
||||
};
|
||||
|
||||
|
||||
const hideAlert = () => {
|
||||
setAlertInfo({ ...alertInfo, visible: false });
|
||||
};
|
||||
|
||||
|
||||
const handleContinue = async () => {
|
||||
if (mobile.length === 10) {
|
||||
setLoading(true);
|
||||
@@ -87,58 +103,64 @@ export default function LoginScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const colorsBlocks = [
|
||||
colors.pastelPink,
|
||||
colors.pastelBlue,
|
||||
colors.pastelGreen,
|
||||
colors.pastelOrange,
|
||||
colors.pastelBlue,
|
||||
colors.pastelPink,
|
||||
colors.pastelGreen,
|
||||
colors.pastelOrange,
|
||||
colors.pastelPink,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard,
|
||||
];
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar barStyle="dark-content" backgroundColor={colors.pastelOrange} />
|
||||
|
||||
{/* Funky grid blocks background (Unchanged) */}
|
||||
<View style={styles.gridContainer}>
|
||||
{colorsBlocks.map((bgColor, index) => (
|
||||
<View
|
||||
key={index}
|
||||
style={[
|
||||
styles.gridBlock,
|
||||
{ backgroundColor: bgColor },
|
||||
index % 2 === 0 ? styles.elevatedBlock : {},
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
return (
|
||||
<View style={[ styles.container, {backgroundColor: theme.colors.background }]}>
|
||||
<StatusBar barStyle={theme.mode === "dark" ? "light-content" : "dark-content"} backgroundColor={colors.pastelOrange} />
|
||||
|
||||
|
||||
{/* Funky grid blocks background (Unchanged) */}
|
||||
<View style={styles.gridContainer}>
|
||||
{colorsBlocks.map((bgColor, index) => (
|
||||
<View
|
||||
key={index}
|
||||
style={[
|
||||
styles.gridBlock,
|
||||
{ backgroundColor: bgColor ,borderRadius:16 },
|
||||
index % 2 === 0 ? styles.elevatedBlock : {},
|
||||
]}
|
||||
/>
|
||||
|
||||
))}
|
||||
</View>
|
||||
|
||||
|
||||
<KeyboardAvoidingView
|
||||
style={styles.keyboardAvoidingContainer}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
>
|
||||
<View style={styles.contentContainer}>
|
||||
<View style={styles.topSection}>
|
||||
<View style={[ styles.topSection, {marginTop:60}]}>
|
||||
<Animated.View style={{ opacity: fade, transform: [{ translateY: slide }] }}>
|
||||
<Text style={styles.brand}>CircleCollect</Text>
|
||||
<Text style={styles.title}>Welcome Back!</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
<Text style={[styles.brand, { color: theme.colors.textPrimary }]}>CircleCollect</Text>
|
||||
<Text style={[styles.title, { color: theme.colors.textPrimary }]}>Welcome Back!</Text>
|
||||
<Text style={[styles.subtitle, { color: theme.colors.textSecondary }]}>
|
||||
Let's get you signed in to your community.
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
|
||||
<Animated.View style={{ opacity: fade, transform: [{ translateY: slide }] }}>
|
||||
<View style={styles.inputWrapper}>
|
||||
<Ionicons name="call-outline" size={24} color={colors.textLight} style={styles.inputIcon} />
|
||||
|
||||
<Animated.View style={{ opacity: fade, transform: [{ translateY: slide }] ,marginTop: 150}}>
|
||||
<View style={[styles.inputWrapper, { backgroundColor: theme.colors.reverseBackground }]}>
|
||||
<Ionicons name="call-outline" size={24} color={theme.colors.reverseText} style={styles.inputIcon} />
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
style={[ styles.input, { color: theme.colors.reverseText, fontFamily: FontsFamily.nunitoRegular }]}
|
||||
placeholder="Enter your mobile number"
|
||||
placeholderTextColor={colors.textLight}
|
||||
placeholderTextColor={theme.colors.reverseText}
|
||||
value={mobile}
|
||||
onChangeText={setMobile}
|
||||
keyboardType="phone-pad"
|
||||
@@ -148,7 +170,8 @@ export default function LoginScreen() {
|
||||
</View>
|
||||
</Animated.View>
|
||||
|
||||
<Animated.View style={[styles.bottomSection, { transform: [{ scale: ctaScale }] }]}>
|
||||
|
||||
<Animated.View style={[styles.bottomSection, { transform: [{ scale: ctaScale }] }]}>
|
||||
<MaterialRipple
|
||||
onPress={handleContinue}
|
||||
disabled={loading}
|
||||
@@ -157,21 +180,16 @@ export default function LoginScreen() {
|
||||
rippleCentered
|
||||
rippleContainerBorderRadius={30}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={[colors.pastelPink, colors.pastelOrange]}
|
||||
style={styles.buttonGradient}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
>
|
||||
<View style={[styles.buttonGradient, { backgroundColor: theme.colors.reverseBackground }]} >
|
||||
{loading ? (
|
||||
<ActivityIndicator color={colors.white} />
|
||||
<ActivityIndicator color={theme.colors.reverseText} />
|
||||
) : (
|
||||
<View style={styles.buttonContent}>
|
||||
<Text style={styles.buttonText}>Continue</Text>
|
||||
<Ionicons name="arrow-forward-circle-outline" size={22} color={colors.white} style={{marginLeft: 8}} />
|
||||
<Text style={[styles.buttonText, { color: theme.colors.reverseText }]}>Continue</Text>
|
||||
<Ionicons name="arrow-forward-circle-outline" size={22} color={theme.colors.reverseText} style={{marginLeft: 8}} />
|
||||
</View>
|
||||
)}
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</MaterialRipple>
|
||||
<Text style={styles.footerText}>
|
||||
Your privacy is our priority. Your information is always secure.
|
||||
@@ -180,6 +198,7 @@ export default function LoginScreen() {
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
|
||||
<CustomAlert
|
||||
visible={alertInfo.visible}
|
||||
title={alertInfo.title}
|
||||
@@ -191,6 +210,7 @@ export default function LoginScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
@@ -207,11 +227,11 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 16,
|
||||
},
|
||||
elevatedBlock: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 5 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 10,
|
||||
elevation: 7,
|
||||
shadowColor: '#ffffffff',
|
||||
shadowOffset: { width: 1, height: 5 },
|
||||
shadowOpacity: 1,
|
||||
shadowRadius: 15,
|
||||
elevation: 10,
|
||||
},
|
||||
keyboardAvoidingContainer: {
|
||||
flex: 1,
|
||||
@@ -227,8 +247,7 @@ const styles = StyleSheet.create({
|
||||
alignItems: 'center',
|
||||
},
|
||||
brand: {
|
||||
fontSize: responsiveFontSize(2.8),
|
||||
fontWeight: '700',
|
||||
fontSize: responsiveFontSize(3),
|
||||
color: colors.primary,
|
||||
textAlign: 'center',
|
||||
letterSpacing: 2,
|
||||
@@ -236,33 +255,29 @@ const styles = StyleSheet.create({
|
||||
textShadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||
textShadowOffset: { width: 1, height: 1 },
|
||||
textShadowRadius: 2,
|
||||
fontFamily: FontsFamily.nunitoExtraBold,
|
||||
},
|
||||
title: {
|
||||
fontSize: responsiveFontSize(4),
|
||||
fontWeight: 'bold',
|
||||
color: colors.textDark,
|
||||
fontSize: responsiveFontSize(5),
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
|
||||
textAlign: 'center',
|
||||
marginBottom: 14,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: responsiveFontSize(1.6),
|
||||
color: colors.textDark,
|
||||
fontFamily: FontsFamily.nunitoRegular,
|
||||
textAlign: 'center',
|
||||
|
||||
lineHeight: 26,
|
||||
maxWidth: 320,
|
||||
},
|
||||
inputWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.85)',
|
||||
borderRadius: 36,
|
||||
borderWidth: 2,
|
||||
borderColor: colors.pastelPink,
|
||||
paddingHorizontal: 20,
|
||||
shadowColor: colors.primary,
|
||||
shadowOffset: { width: 0, height: 6 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 14,
|
||||
paddingHorizontal: responsiveHeight(2),
|
||||
elevation: 8,
|
||||
},
|
||||
inputIcon: {
|
||||
@@ -271,9 +286,9 @@ const styles = StyleSheet.create({
|
||||
input: {
|
||||
flex: 1,
|
||||
fontSize: responsiveFontSize(1.8),
|
||||
fontWeight: '600',
|
||||
fontFamily: FontsFamily.nunitoSemiBold,
|
||||
color: colors.textLight,
|
||||
height: 58,
|
||||
height: responsiveHeight(5),
|
||||
},
|
||||
bottomSection: {
|
||||
alignItems: 'center',
|
||||
@@ -282,16 +297,13 @@ const styles = StyleSheet.create({
|
||||
button: {
|
||||
width: '100%',
|
||||
borderRadius: 30,
|
||||
shadowColor: colors.primary,
|
||||
shadowOffset: { width: 0, height: 10 },
|
||||
shadowOpacity: 0.4,
|
||||
shadowRadius: 20,
|
||||
elevation: 14,
|
||||
marginTop: 20,
|
||||
},
|
||||
buttonGradient: {
|
||||
borderRadius: 30,
|
||||
paddingVertical: 18,
|
||||
|
||||
borderRadius:42,
|
||||
paddingVertical: 14,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
@@ -302,8 +314,8 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
buttonText: {
|
||||
color: colors.white,
|
||||
fontWeight: '800',
|
||||
fontSize: responsiveFontSize(1.8),
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
},
|
||||
footerText: {
|
||||
fontSize: responsiveFontSize(1.4),
|
||||
@@ -311,5 +323,6 @@ const styles = StyleSheet.create({
|
||||
marginTop: 28,
|
||||
textAlign: 'center',
|
||||
maxWidth: 300,
|
||||
fontFamily: FontsFamily.nunitoRegular,
|
||||
},
|
||||
});
|
||||
@@ -21,6 +21,8 @@ import { LOGIN_URL, VARIFY_OTP_URL } from "../utils/ApiUrls";
|
||||
import colors from "../components/colors";
|
||||
import CustomAlert from "../components/CostomAlart";
|
||||
import { getFcmToken } from "../utils/firebase/firebaseServices";
|
||||
import { useTheme } from "../theme/ThemeProvider";
|
||||
import FontsFamily from "../constents/FontsFamily";
|
||||
|
||||
const CELL_COUNT = 6;
|
||||
const { width } = Dimensions.get('window');
|
||||
@@ -50,6 +52,7 @@ export default function OtpVerificationScreen() {
|
||||
buttons: [],
|
||||
alertType: "info",
|
||||
});
|
||||
const { theme } = useTheme();
|
||||
|
||||
const inputs = useRef<Array<TextInput | null>>([]);
|
||||
const route = useRoute<OtpVerifyRouteProp>();
|
||||
@@ -133,17 +136,17 @@ export default function OtpVerificationScreen() {
|
||||
await getFcmToken(res.data?.data?.userId);
|
||||
|
||||
let hasActionRun = false;
|
||||
const successAction = () => {
|
||||
if (hasActionRun) return;
|
||||
hasActionRun = true;
|
||||
hideAlert();
|
||||
navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: 'Home' }],
|
||||
})
|
||||
);
|
||||
};
|
||||
const successAction = () => {
|
||||
if (hasActionRun) return;
|
||||
hasActionRun = true;
|
||||
hideAlert();
|
||||
navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: 'Home' }],
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
triggerAlert(
|
||||
'Success!',
|
||||
@@ -238,56 +241,64 @@ export default function OtpVerificationScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
const colorsBlocks = [
|
||||
colors.pastelPink,
|
||||
colors.pastelBlue,
|
||||
colors.pastelGreen,
|
||||
colors.pastelOrange,
|
||||
colors.pastelBlue,
|
||||
colors.pastelPink,
|
||||
colors.pastelGreen,
|
||||
colors.pastelOrange,
|
||||
colors.pastelPink,
|
||||
const colorsBlocks = [
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard1,
|
||||
theme.colors.logincard,
|
||||
theme.colors.logincard,
|
||||
];
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar barStyle="dark-content" backgroundColor={colors.pastelOrange} />
|
||||
<View style={[styles.container, {backgroundColor: theme.colors.background }]}>
|
||||
<StatusBar barStyle={theme.mode === "dark" ? "light-content" : "dark-content"} backgroundColor={colors.pastelOrange} />
|
||||
|
||||
<View style={styles.gridContainer}>
|
||||
{colorsBlocks.map((bgColor, index) => (
|
||||
<View
|
||||
key={index}
|
||||
style={[
|
||||
styles.gridBlock,
|
||||
{ backgroundColor: bgColor },
|
||||
index % 2 === 0 ? styles.elevatedBlock : {},
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
<View
|
||||
key={index}
|
||||
style={[
|
||||
styles.gridBlock,
|
||||
{ backgroundColor: bgColor, borderRadius: 16 },
|
||||
index % 2 === 0 ? styles.elevatedBlock : {},
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<KeyboardAvoidingView style={styles.keyboardAvoidingContainer} behavior={Platform.OS === "ios" ? "padding" : undefined}>
|
||||
|
||||
<CustomAlert {...alertConfig} />
|
||||
|
||||
<View style={styles.contentPanel}>
|
||||
<View style={[styles.contentPanel, { backgroundColor: theme.colors.reverseBackground }]}>
|
||||
<View style={styles.topSection}>
|
||||
<Text style={styles.title}>Verify Your Code</Text>
|
||||
<Text style={styles.subtitle}>We’ve sent a 6-digit verification code to +91 {mobile}.</Text>
|
||||
<Text style={[styles.title, { color: theme.colors.reverseText }]}>Verify Your Code</Text>
|
||||
<Text style={[styles.subtitle, { color: theme.colors.reverseText }]}>We’ve sent a 6-digit verification code to +91 {mobile}.</Text>
|
||||
|
||||
<Animated.View style={[styles.otpRow, { opacity: fade, transform: [{ translateY: slide }] }]}>
|
||||
<Animated.View style={[styles.otpRow, { transform: [{ translateY: slide }] }]}>
|
||||
{Array.from({ length: CELL_COUNT }).map((_, i) => (
|
||||
<TextInput
|
||||
key={`otp-${i}`}
|
||||
ref={(r) => { inputs.current[i] = r; }}
|
||||
style={[styles.cell, code[i] ? styles.cellFilled : null]}
|
||||
// UPDATED CELL STYLE
|
||||
style={[
|
||||
styles.cell,
|
||||
code[i] ? styles.cellFilled : null,
|
||||
{
|
||||
backgroundColor: theme.colors.optCard,
|
||||
color: theme.colors.reverseText,
|
||||
}
|
||||
]}
|
||||
|
||||
keyboardType="number-pad"
|
||||
maxLength={i === 0 ? CELL_COUNT : 1}
|
||||
value={code[i]}
|
||||
onChangeText={(t) => (i === 0 ? handleFirstCellChange(t) : updateIndex(i, t))}
|
||||
onKeyPress={(e) => handleKeyPress(i, e)}
|
||||
placeholder="•"
|
||||
placeholder="*"
|
||||
placeholderTextColor="#BDBDBD"
|
||||
textContentType="oneTimeCode"
|
||||
/>
|
||||
@@ -300,16 +311,16 @@ export default function OtpVerificationScreen() {
|
||||
onPressIn={() => Animated.spring(ctaScale, { toValue: 0.97, useNativeDriver: true }).start()}
|
||||
onPressOut={() => Animated.spring(ctaScale, { toValue: 1, useNativeDriver: true }).start()}
|
||||
onPress={() => onSubmit(code.join(""), mobile)}
|
||||
style={styles.button}
|
||||
style={[styles.button, { backgroundColor: theme.colors.background }]}
|
||||
>
|
||||
<Text style={styles.buttonText}>Verify & Continue</Text>
|
||||
<Text style={[styles.buttonText, { color: theme.colors.textPrimary }]}>Verify & Continue</Text>
|
||||
</Pressable>
|
||||
|
||||
{timer > 0 ? (
|
||||
<Text style={styles.footerText}>Resend code in 00:{timer.toString().padStart(2, "0")}</Text>
|
||||
<Text style={[styles.footerText, { color: theme.colors.reverseText }]}>Resend code in 00:{timer.toString().padStart(2, "0")}</Text>
|
||||
) : (
|
||||
<Pressable onPress={resendOtp} disabled={isResending}>
|
||||
<Text style={[styles.footerText, { color: colors.pastelPink, fontWeight: '600' }]}>
|
||||
<Text style={[styles.footerText, { color: theme.colors.reverseText, fontWeight: '600' }]}>
|
||||
{isResending ? "Resending..." : "Resend Code"}
|
||||
</Text>
|
||||
</Pressable>
|
||||
@@ -335,16 +346,15 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 16,
|
||||
},
|
||||
elevatedBlock: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 5 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 10,
|
||||
elevation: 7,
|
||||
shadowColor: '#ffffffff',
|
||||
shadowOffset: { width: 1, height: 5 },
|
||||
shadowOpacity: 1,
|
||||
shadowRadius: 15,
|
||||
elevation: 10,
|
||||
},
|
||||
keyboardAvoidingContainer: { flex: 1, justifyContent: 'center' },
|
||||
contentPanel: {
|
||||
marginHorizontal: 24,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
||||
borderRadius: 32,
|
||||
padding: 28,
|
||||
shadowColor: '#000',
|
||||
@@ -354,13 +364,33 @@ const styles = StyleSheet.create({
|
||||
elevation: 12,
|
||||
},
|
||||
topSection: { alignItems: 'center', marginBottom: 24 },
|
||||
title: { fontSize: 28, fontWeight: "bold", color: colors.textDark, textAlign: 'center', marginBottom: 12 },
|
||||
subtitle: { fontSize: 16, color: colors.textLight, textAlign: 'center', marginBottom: 32, lineHeight: 24, maxWidth: 300 },
|
||||
otpRow: { flexDirection: "row", justifyContent: "space-between", width: '100%', paddingHorizontal: 10 },
|
||||
cell: { width: 48, height: 56, borderRadius: 12, borderWidth: 1.5, borderColor: colors.inputBorder, backgroundColor: colors.white, textAlign: "center", fontSize: 22, fontWeight: '700', color: colors.textDark, shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 8, elevation: 3 },
|
||||
cellFilled: { borderColor: colors.primary, backgroundColor: '#F7F2FF' },
|
||||
title: { fontSize: 28, color: colors.textDark, textAlign: 'center', marginBottom: 12 ,fontFamily: FontsFamily.nunitoExtraBold},
|
||||
subtitle: { fontSize: 16, color: colors.textLight, textAlign: 'center', marginBottom: 32, lineHeight: 24, maxWidth: 300 ,fontFamily: FontsFamily.nunitoMedium},
|
||||
|
||||
otpRow: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
width: '100%',
|
||||
paddingHorizontal: 0, // Removed padding to use full width
|
||||
},
|
||||
|
||||
// FIX: Updated Cell Styling for clean smooth radius
|
||||
cell: {
|
||||
width: 45,
|
||||
height: 52,
|
||||
borderRadius: 14, // Smoother radius
|
||||
textAlign: "center",
|
||||
fontSize: 20,
|
||||
fontWeight: "600",
|
||||
elevation: 0, // Removed elevation for flat look (or keep if you want shadow)
|
||||
overflow: 'hidden',
|
||||
},
|
||||
cellFilled: {
|
||||
// Optional: Add specific style when filled if needed, handled inline above
|
||||
},
|
||||
|
||||
bottomSection: { paddingBottom: Platform.OS === "ios" ? 20 : 10, paddingTop: 10 },
|
||||
button: { backgroundColor: colors.pastelPink, paddingVertical: 18, borderRadius: 30, alignItems: "center", justifyContent: "center", shadowColor: colors.primary, shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.3, shadowRadius: 15, elevation: 8 ,borderWidth:2, borderColor:colors.pastelPink},
|
||||
buttonText: { color: colors.white, fontWeight: "700", fontSize: 16 },
|
||||
footerText: { textAlign: "center", color: colors.textLight, fontSize: 14, marginTop: 20 },
|
||||
button: { backgroundColor: colors.pastelPink, paddingVertical: 18, borderRadius: 30, alignItems: "center", justifyContent: "center",},
|
||||
buttonText: { color: colors.white, fontSize: 16, fontFamily: FontsFamily.nunitoBold },
|
||||
footerText: { textAlign: "center", fontFamily: FontsFamily.nunitoBold, fontSize: 14, marginTop: 20 },
|
||||
});
|
||||
|
||||
+19
-11
@@ -10,6 +10,7 @@ import {
|
||||
ListRenderItem,
|
||||
Alert,
|
||||
RefreshControl,
|
||||
StatusBar,
|
||||
} from "react-native";
|
||||
import AppView from "../../components/AppView";
|
||||
import colors from "../../components/colors";
|
||||
@@ -23,6 +24,10 @@ import AnimatedCard from "../../components/common/AnimatedCard";
|
||||
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
||||
import { apiCall } from "../../utils/ApiHelper";
|
||||
import CustomAlert, { CustomAlertProps } from "../../components/CostomAlart";
|
||||
import { useTheme } from "../../theme/ThemeProvider";
|
||||
import FontsFamily from "../../constents/FontsFamily";
|
||||
import { responsiveFontSize, responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) {
|
||||
UIManager.setLayoutAnimationEnabledExperimental(true);
|
||||
@@ -80,6 +85,8 @@ const Home: React.FC = () => {
|
||||
const [userDashboard, setUserDashboard] = useState<any>(null);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [statusData, setStatusData] = useState<any>(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const {theme} = useTheme();
|
||||
const getDashboardData = async () => {
|
||||
try {
|
||||
const result = (await apiCall(DASHBOARD_URL, "GET")) as any;
|
||||
@@ -186,7 +193,8 @@ const Home: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AppView barStyle="dark-content" style={styles.container}>
|
||||
<View style={[ styles.container, {backgroundColor: theme.colors.background, paddingBottom: insets.bottom + responsiveHeight(10) }]}>
|
||||
<StatusBar barStyle={theme.mode === "dark" ? "light-content" : "dark-content"}/>
|
||||
<FlatList
|
||||
data={actions}
|
||||
numColumns={2}
|
||||
@@ -195,18 +203,19 @@ const Home: React.FC = () => {
|
||||
ListHeaderComponent={
|
||||
<>
|
||||
<View style={styles.header}>
|
||||
<View>
|
||||
<Text style={styles.greeting}>
|
||||
Hello, <Text style={{ fontWeight: 'bold' }}>{user.firstName || apiUser?.firstName || "User"}</Text>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 ,marginTop: responsiveHeight(2) }} >
|
||||
<Text style={[styles.greeting, { color: theme.colors.textPrimary }]}>
|
||||
Hello,
|
||||
</Text>
|
||||
<Text style={{ fontFamily:FontsFamily.nunitoExtraBold,color: theme.colors.textPrimary,fontSize:responsiveFontSize(2.5) }}>{user.firstName || apiUser?.firstName || "User"}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => navigation.navigate("Notification" as never)}>
|
||||
<TouchableOpacity onPress={() => navigation.navigate("Notification" as never)} style={{ marginTop: responsiveHeight(2) ,}}>
|
||||
{unreadCount > 0 && (
|
||||
<View style={styles.badge}>
|
||||
<Text style={styles.badgeText}>{unreadCount}</Text>
|
||||
</View>
|
||||
)}
|
||||
<Ionicons name="notifications-outline" size={30} color={colors.textDark} />
|
||||
<Ionicons name="notifications-outline" size={30} color={theme.colors.textPrimary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -217,7 +226,7 @@ const Home: React.FC = () => {
|
||||
/>
|
||||
|
||||
<View style={styles.actionHeader}>
|
||||
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
||||
<Text style={[styles.sectionTitle,{ color: theme.colors.textPrimary }]}>Quick Actions </Text>
|
||||
|
||||
</View>
|
||||
</>
|
||||
@@ -243,7 +252,7 @@ const Home: React.FC = () => {
|
||||
onClose={() => setAlertVisible(false)}
|
||||
/>
|
||||
)}
|
||||
</AppView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -252,7 +261,6 @@ export default Home;
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
@@ -262,8 +270,8 @@ const styles = StyleSheet.create({
|
||||
paddingTop: 24,
|
||||
paddingBottom: 16,
|
||||
},
|
||||
greeting: { fontSize: 22, color: colors.textDark },
|
||||
sectionTitle: { fontSize: 20, fontWeight: "600", color: colors.textDark, flex: 1 },
|
||||
greeting: { fontSize: 22,fontFamily: FontsFamily.nunitoLight },
|
||||
sectionTitle: { fontSize: 20, fontWeight: "600", color: colors.textDark, flex: 1 ,fontFamily: FontsFamily.nunitoSemiBold},
|
||||
actionHeader: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
|
||||
@@ -21,6 +21,8 @@ import {
|
||||
responsiveWidth,
|
||||
responsiveFontSize
|
||||
} from "react-native-responsive-dimensions";
|
||||
import { useTheme } from "../../theme/ThemeProvider";
|
||||
import FontsFamily from "../../constents/FontsFamily";
|
||||
|
||||
type StatusData = {
|
||||
role?: string;
|
||||
@@ -73,7 +75,7 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
const [showPayDialog, setShowPayDialog] = useState(false);
|
||||
const [selectedGroupIds, setSelectedGroupIds] = useState<string[]>([]);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const {theme} = useTheme();
|
||||
// console.log("user me : ", userDashboard)
|
||||
// Preselect all due groups at mount and on change
|
||||
useEffect(() => {
|
||||
@@ -92,12 +94,12 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
// Top grid info items
|
||||
const infoItems = useMemo(
|
||||
() => [
|
||||
{ icon: <Ionicons name="person-outline" size={20} color={colors.primary} />, label: "Role", value: statusData?.role || "-" },
|
||||
{ icon: <Ionicons name="pie-chart-outline" size={20} color={colors.primary} />, label: "Active Groups", value: userDashboard?.activeStatusMyGroupCount?.toString() || "0" },
|
||||
{ icon: <Ionicons name="book-outline" size={20} color={colors.primary} />, label: "Joined Groups", value: userDashboard?.myJoinedGroups?.length?.toString() || "0" },
|
||||
{ icon: <Ionicons name="people-outline" size={20} color={colors.primary} />, label: "My Groups", value: userDashboard?.myCreatedGroups?.length?.toString() || "0" },
|
||||
{ icon: <Ionicons name="document-text-outline" size={20} color={colors.primary} />, label: "Total Due", value: `₹${userDashboard?.multiplePayAmount || 0}` },
|
||||
{ icon: <Ionicons name="checkmark-done-outline" size={20} color={colors.primary} />, label: "Completed", value: userDashboard?.completeStatusMyGroupCount?.toString() || "0" },
|
||||
{ icon: <Ionicons name="person-outline" size={20} color={theme.colors.black} />, label: "Role", value: statusData?.role || "-" },
|
||||
{ icon: <Ionicons name="pie-chart-outline" size={20} color={theme.colors.black} />, label: "Active Groups", value: userDashboard?.activeStatusMyGroupCount?.toString() || "0" },
|
||||
{ icon: <Ionicons name="book-outline" size={20} color={theme.colors.black} />, label: "Joined Groups", value: userDashboard?.myJoinedGroups?.length?.toString() || "0" },
|
||||
{ icon: <Ionicons name="people-outline" size={20} color={theme.colors.black} />, label: "My Groups", value: userDashboard?.myCreatedGroups?.length?.toString() || "0" },
|
||||
{ icon: <Ionicons name="document-text-outline" size={20} color={theme.colors.black} />, label: "Total Due", value: `₹${userDashboard?.multiplePayAmount || 0}` },
|
||||
{ icon: <Ionicons name="checkmark-done-outline" size={20} color={theme.colors.black} />, label: "Completed", value: userDashboard?.completeStatusMyGroupCount?.toString() || "0" },
|
||||
],
|
||||
[userDashboard, statusData]
|
||||
);
|
||||
@@ -153,18 +155,18 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
|
||||
// Bottom bar
|
||||
const renderDueBar = () => (
|
||||
<View style={styles.dueBar}>
|
||||
<Text style={styles.dueBarText}>
|
||||
Total Due: <Text style={{ color: "#FFDE03", fontWeight: "bold" }}>₹{totalDue}</Text>
|
||||
<View style={[ styles.dueBar, { borderTopColor: theme.colors.border, backgroundColor: theme.colors.gray }]}>
|
||||
<Text style={[styles.dueBarText, { color: theme.colors.black }]}>
|
||||
Total Due: <Text style={{ color: theme.colors.black, fontWeight: "bold" }}>₹{totalDue}</Text>
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.payAllButton}
|
||||
style={[styles.payAllButton, { backgroundColor: theme.colors.black }]}
|
||||
onPress={() => setShowPayDialog(true)}
|
||||
disabled={dueGroups.length === 0}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Ionicons name="wallet-outline" size={20} color="#000000ff" />
|
||||
<Text style={styles.payAllButtonText}>Pay All</Text>
|
||||
<Ionicons name="wallet-outline" size={20} color={theme.colors.white} />
|
||||
<Text style={[styles.payAllButtonText, { color: theme.colors.white }]}>Pay All</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
@@ -173,17 +175,14 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
const renderPayDialog = () => (
|
||||
<Modal visible={showPayDialog} transparent animationType="fade" onRequestClose={() => setShowPayDialog(false)}>
|
||||
<View style={styles.payModalOverlay}>
|
||||
<LinearGradient
|
||||
colors={[colors.white, colors.white]}
|
||||
start={{ x: 0.2, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
style={styles.payModalBox}
|
||||
<View
|
||||
style={[styles.payModalBox, { backgroundColor: theme.colors.reverseBackground }]}
|
||||
>
|
||||
<View style={styles.payDialogHeader}>
|
||||
<Ionicons name="card-outline" color="#000000ff" size={22} />
|
||||
<Text style={styles.payDialogTitle}>Select Groups to Pay</Text>
|
||||
<Ionicons name="card-outline" color={theme.colors.reverseText} size={22} />
|
||||
<Text style={[styles.payDialogTitle, { color: theme.colors.reverseText }]}>Select Groups to Pay</Text>
|
||||
<TouchableOpacity onPress={() => setShowPayDialog(false)}>
|
||||
<Ionicons name="close-circle" color="#000000ff" size={24} />
|
||||
<Ionicons name="close-circle" color={theme.colors.reverseText} size={24} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<ScrollView
|
||||
@@ -193,70 +192,73 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
{dueGroups.map((group) => (
|
||||
<TouchableOpacity
|
||||
key={group.groupId}
|
||||
style={[
|
||||
styles.payGroupOption,
|
||||
selectedGroupIds.includes(group.groupId) && styles.payOptionSelected,
|
||||
]}
|
||||
style={[
|
||||
styles.payGroupOption,
|
||||
{ borderColor: theme.colors.background, borderWidth: 1 },
|
||||
|
||||
selectedGroupIds.includes(group.groupId) && {
|
||||
...styles.payOptionSelected,
|
||||
borderColor: theme.colors.reverseBackground,
|
||||
},
|
||||
]}
|
||||
|
||||
onPress={() => handleToggleGroup(group.groupId)}
|
||||
activeOpacity={0.85}
|
||||
>
|
||||
<Ionicons
|
||||
name={selectedGroupIds.includes(group.groupId) ? "checkbox" : "square-outline"}
|
||||
size={22}
|
||||
color={selectedGroupIds.includes(group.groupId) ? colors.primary : "#000000ff"}
|
||||
color={selectedGroupIds.includes(group.groupId) ? theme.colors.reverseText : theme.colors.reverseText}
|
||||
/>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text style={[styles.payGroupName, { color: "#000000ff" }]}>{group.groupName}</Text>
|
||||
<Text style={styles.payDueText}>
|
||||
<Text style={[styles.payGroupName, {color: theme.colors.reverseText}]}>{group.groupName}</Text>
|
||||
<Text style={[styles.payDueText, {color: theme.colors.reverseText}]}>
|
||||
₹{group.baseAmount}
|
||||
{group.lateFee > 0 ? ` (Late: ₹${group.lateFee})` : ""}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={[styles.payAmount, { color: "#4CAF50" }]}>₹{group.totalDue}</Text>
|
||||
{/* <Text style={[styles.payAmount, { color: "#4CAF50" }]}>₹{group.totalDue}</Text> */}
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
<View style={styles.payDialogFooter}>
|
||||
<Text style={styles.payDialogTotal}>
|
||||
Total: <Text style={{ fontWeight: "bold", color: "#ff5f03ff" }}>₹{totalDueSelected}</Text>
|
||||
<Text style={[styles.payDialogTotal, { color: theme.colors.reverseText }]}>
|
||||
Total : <Text style={{ fontFamily: FontsFamily.nunitoBold, color: theme.colors.red }}>₹{totalDueSelected}</Text>
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.payConfirmButton, { opacity: submitting ? 0.7 : 1 }]}
|
||||
style={[styles.payConfirmButton, { opacity: submitting ? 0.7 : 1 , backgroundColor: theme.colors.background}]}
|
||||
onPress={handlePayAll}
|
||||
disabled={submitting || selectedGroupIds.length === 0}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{submitting ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
<ActivityIndicator color={theme.colors.textPrimary} />
|
||||
) : (
|
||||
<>
|
||||
<Ionicons name="checkmark-circle" size={22} color="#ffffffff" />
|
||||
<Text style={styles.payButtonText}>Pay Selected</Text>
|
||||
<Ionicons name="checkmark-circle" size={22} color={theme.colors.textPrimary} />
|
||||
<Text style={[styles.payButtonText, { fontFamily: FontsFamily.nunitoSemiBold ,color: theme.colors.textPrimary}]}>Pay Selected</Text>
|
||||
</>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<LinearGradient
|
||||
colors={[colors.primary, colors.pastelPink]}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
style={styles.card}
|
||||
<View
|
||||
style={[styles.card, { backgroundColor: theme.colors.reverseBackground }]}
|
||||
>
|
||||
<View style={styles.headerSection}>
|
||||
<View style={styles.titleWithIcon}>
|
||||
<Ionicons name="stats-chart" size={24} color="#fff" style={styles.headerIcon} />
|
||||
<Text style={styles.header}>Profile Overview</Text>
|
||||
<Ionicons name="stats-chart" size={24} color={theme.colors.reverseText} style={styles.headerIcon} />
|
||||
<Text style={[styles.header, { color: theme.colors.reverseText} ]}>Profile Overview</Text>
|
||||
</View>
|
||||
<View style={styles.statusBadge}>
|
||||
<Ionicons name="shield-checkmark" size={16} color="#fff" />
|
||||
<Text style={styles.statusBadgeText}>
|
||||
<View style={[styles.statusBadge, { backgroundColor: theme.colors.background}]}>
|
||||
<Ionicons name="shield-checkmark" size={16} color={theme.colors.textPrimary} />
|
||||
<Text style={[styles.statusBadgeText, { color: theme.colors.textPrimary }]}>
|
||||
{statusData?.profileStatus ? "Verified" : "Pending"}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -265,16 +267,16 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
<View style={styles.leftSection}>
|
||||
<View style={styles.infoGrid}>
|
||||
{infoItems.map((item, idx) => (
|
||||
<View key={item.label} style={styles.infoCard}>
|
||||
<View key={item.label} style={[styles.infoCard,{backgroundColor: theme.colors.background}]}>
|
||||
<View style={styles.infoCardHeader}>
|
||||
<View style={styles.iconContainer}>
|
||||
<View style={[styles.iconContainer, {backgroundColor: theme.colors.optCard || theme.colors.card}]}>
|
||||
{item.icon}
|
||||
</View>
|
||||
<Text style={styles.infoLabel} >
|
||||
<Text style={[styles.infoLabel,{color: theme.colors.textPrimary}]} >
|
||||
{item.label}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={[styles.infoValue, { color: getValueColor(item.value) }]} numberOfLines={1}>
|
||||
<Text style={[styles.infoValue, { color: theme.colors.textPrimary }]} numberOfLines={1}>
|
||||
{item.value}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -296,16 +298,16 @@ const UserProfileStatus: React.FC<UserProfileStatusProps> = ({
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.infoCardOne}>
|
||||
<Text style={{ color: "#fff", fontSize: responsiveWidth(2.3)}}>Total Paid Amount <Text style={{ fontWeight: "900"}}>{userDashboard?.totalPaidAmountMonth}</Text></Text>
|
||||
{/* <Text style={{ color: "#fff", fontWeight: "400"}}>Total Paid Amount {userDashboard?.totalPaidAmountMonth}</Text> */}
|
||||
<View style={[styles.infoCardOne,{backgroundColor: theme.colors.background}]}>
|
||||
<Text style={{ color: theme.colors.textPrimary, fontSize: responsiveWidth(3), fontFamily: FontsFamily.nunitoSemiBold,}}>Total Paid Amount</Text>
|
||||
<Text style={{ color: theme.colors.textPrimary, fontWeight: "400", fontFamily: FontsFamily.nunitoRegular}}>{userDashboard?.totalPaidAmountMonth}</Text>
|
||||
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
{renderDueBar()}
|
||||
</LinearGradient>
|
||||
</View>
|
||||
|
||||
{renderPayDialog()}
|
||||
|
||||
@@ -377,8 +379,8 @@ const styles = StyleSheet.create({
|
||||
marginRight: 8
|
||||
},
|
||||
header: {
|
||||
fontSize: responsiveWidth(3.5),
|
||||
fontWeight: "700",
|
||||
fontSize: responsiveWidth(4.5),
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
color: "#fff"
|
||||
},
|
||||
statusBadge: {
|
||||
@@ -411,14 +413,11 @@ const styles = StyleSheet.create({
|
||||
gap: 10
|
||||
},
|
||||
infoCard: {
|
||||
backgroundColor: 'rgba(255,255,255,0.15)',
|
||||
borderRadius: 14,
|
||||
padding: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(255,255,255,0.2)',
|
||||
flex: 1,
|
||||
minWidth: '45%',
|
||||
marginBottom: 8,
|
||||
borderRadius:12
|
||||
},
|
||||
infoCardOne: {
|
||||
backgroundColor: 'rgba(255,255,255,0.15)',
|
||||
@@ -436,25 +435,22 @@ const styles = StyleSheet.create({
|
||||
marginBottom: 6
|
||||
},
|
||||
iconContainer: {
|
||||
width: 28,
|
||||
height: 28,
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 8,
|
||||
width: responsiveWidth(8),
|
||||
height: responsiveHeight(3.5),
|
||||
borderRadius: responsiveWidth(2),
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 8,
|
||||
},
|
||||
infoLabel: {
|
||||
color: "rgba(255,255,255,0.9)",
|
||||
fontSize: responsiveWidth(2),
|
||||
fontWeight: '500',
|
||||
fontSize: responsiveWidth(3),
|
||||
fontFamily: FontsFamily.nunitoSemiBold,
|
||||
flexShrink: 1,
|
||||
},
|
||||
infoValue: {
|
||||
fontWeight: "700",
|
||||
fontSize: responsiveWidth(2.5),
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
fontSize: responsiveWidth(3),
|
||||
textAlign: 'left',
|
||||
color: "#fff"
|
||||
},
|
||||
profileSection: {
|
||||
width: 90,
|
||||
@@ -498,16 +494,13 @@ const styles = StyleSheet.create({
|
||||
alignItems: "center",
|
||||
padding: 16,
|
||||
borderTopWidth: 1,
|
||||
borderColor: "rgba(255,255,255,0.15)",
|
||||
backgroundColor: "rgba(0,0,0,0.15)",
|
||||
},
|
||||
dueBarText: {
|
||||
color: "#fff",
|
||||
fontSize: responsiveWidth(2.5),
|
||||
fontWeight: "600"
|
||||
fontFamily: FontsFamily.nunitoExtraBold,
|
||||
fontSize: responsiveWidth(4),
|
||||
|
||||
},
|
||||
payAllButton: {
|
||||
backgroundColor: "#ffffffff",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 16,
|
||||
@@ -516,8 +509,7 @@ const styles = StyleSheet.create({
|
||||
gap: 6,
|
||||
},
|
||||
payAllButtonText: {
|
||||
color: "#000000ff",
|
||||
fontWeight: "bold",
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
fontSize: responsiveWidth(2.5)
|
||||
},
|
||||
payModalOverlay: {
|
||||
@@ -527,7 +519,7 @@ const styles = StyleSheet.create({
|
||||
alignItems: "center",
|
||||
},
|
||||
payModalBox: {
|
||||
width: "92%",
|
||||
width: "90%",
|
||||
borderRadius: 24,
|
||||
overflow: "hidden",
|
||||
alignItems: "center",
|
||||
@@ -547,9 +539,10 @@ const styles = StyleSheet.create({
|
||||
borderColor: "rgba(255,255,255,0.1)",
|
||||
},
|
||||
payDialogTitle: {
|
||||
color: "#000000ff",
|
||||
fontSize: responsiveWidth(1.8),
|
||||
fontWeight: "700"
|
||||
|
||||
fontSize: responsiveWidth(4),
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
|
||||
},
|
||||
payGroupOption: {
|
||||
flexDirection: "row",
|
||||
@@ -557,24 +550,20 @@ const styles = StyleSheet.create({
|
||||
gap: 16,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 14,
|
||||
borderColor: colors.primary,
|
||||
borderWidth: 1,
|
||||
borderRadius: 12,
|
||||
marginBottom: 8,
|
||||
},
|
||||
payOptionSelected: {
|
||||
backgroundColor: "rgba(166, 49, 255, 0.2)",
|
||||
borderColor: colors.primary,
|
||||
|
||||
borderWidth: 1,
|
||||
},
|
||||
payGroupName: {
|
||||
color: "#000000ff",
|
||||
fontWeight: "700",
|
||||
fontSize: responsiveWidth(2.5)
|
||||
fontFamily: FontsFamily.nunitoSemiBold,
|
||||
fontSize: responsiveWidth(3)
|
||||
},
|
||||
payDueText: {
|
||||
color: "rgba(0, 0, 0, 0.8)",
|
||||
fontSize: responsiveWidth(1.3),
|
||||
fontSize: responsiveWidth(3),
|
||||
fontFamily: FontsFamily.nunitoRegular,
|
||||
marginTop: 2
|
||||
},
|
||||
payAmount: {
|
||||
@@ -591,26 +580,23 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 18,
|
||||
},
|
||||
payDialogTotal: {
|
||||
color: "#000000ff",
|
||||
fontWeight: "600",
|
||||
fontSize: responsiveWidth(1.7)
|
||||
fontFamily: FontsFamily.nunitoBold,
|
||||
fontSize: responsiveWidth(3.5)
|
||||
},
|
||||
payConfirmButton: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: colors.primary,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 24,
|
||||
borderRadius: 20,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 18,
|
||||
borderRadius: 12,
|
||||
elevation: 4,
|
||||
borderColor: colors.primary,
|
||||
borderWidth: 1,
|
||||
|
||||
gap: 8,
|
||||
},
|
||||
payButtonText: {
|
||||
color: "#ffffffff",
|
||||
fontWeight: "bold",
|
||||
fontSize: responsiveWidth(2.5)
|
||||
fontSize: responsiveWidth(3),
|
||||
},
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// src/screens/ManagementScreen.tsx
|
||||
// src/screens/ManagementScreen.tsx
|
||||
import React, { useState, useCallback, FC, useEffect } from "react";
|
||||
import {
|
||||
View,
|
||||
|
||||
Reference in New Issue
Block a user