updated code with dsc and device binding
This commit is contained in:
@@ -1,14 +1,20 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { View, Text, Modal, ScrollView, TouchableOpacity, StyleSheet, Dimensions } from 'react-native';
|
||||
import { CheckCircle, X } from 'lucide-react-native'; // Updated icons
|
||||
import colors from '../../Constant/Color';
|
||||
import React, { ReactNode, useMemo } from 'react';
|
||||
import { View, Modal, ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
|
||||
import { CheckCircle, X, FileText, Shield, Users, Brain, Lock, RefreshCw, Scale } from 'lucide-react-native';
|
||||
import Animated, { FadeInUp, FadeInDown, FadeIn } from 'react-native-reanimated';
|
||||
import { useTheme } from '../../Hooks/useTheme';
|
||||
import AppText from '../../components/AppText';
|
||||
|
||||
type ModalProps = {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
onChecked: () => void
|
||||
}
|
||||
onChecked: () => void;
|
||||
};
|
||||
|
||||
const TermsAndConditionsModal: React.FC<ModalProps> = ({ visible, onClose, onChecked }) => {
|
||||
const { colors, spacing, shadows, typography } = useTheme();
|
||||
const styles = useMemo(() => makeStyles(colors, spacing, shadows, typography), [colors, spacing, shadows, typography]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType="slide"
|
||||
@@ -17,185 +23,282 @@ const TermsAndConditionsModal: React.FC<ModalProps> = ({ visible, onClose, onChe
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<ScrollView contentContainerStyle={styles.scrollContainer}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.title}>Terms & Conditions</Text>
|
||||
<Text style={styles.subtitle}>Last updated: {new Date().toLocaleDateString()}</Text>
|
||||
{/* ═══ Header ═══ */}
|
||||
<Animated.View
|
||||
entering={FadeInDown.duration(400).springify()}
|
||||
style={styles.header}
|
||||
>
|
||||
<View style={styles.headerRow}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<AppText variant="h3" color={colors.buttonText} style={{ fontWeight: '800' }}>
|
||||
Terms & Conditions
|
||||
</AppText>
|
||||
<AppText variant="caption" color={`${colors.buttonText}CC`} style={{ marginTop: 4 }}>
|
||||
Last updated: {new Date().toLocaleDateString()}
|
||||
</AppText>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
onPress={onClose}
|
||||
style={styles.closeButton}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<X size={20} color={colors.buttonText} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</Animated.View>
|
||||
|
||||
<View style={styles.content}>
|
||||
<Section title="1. Acceptance of Terms">
|
||||
<Text style={styles.paragraph}>
|
||||
By accessing or using our services, you agree to be bound by these Terms and Conditions.
|
||||
If you do not agree with any part of these terms, you must not use our services.
|
||||
</Text>
|
||||
</Section>
|
||||
{/* ═══ Content ═══ */}
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContainer}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
<Section
|
||||
title="1. Acceptance of Terms"
|
||||
icon={<FileText size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={0}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
By accessing or using our services, you agree to be bound by these Terms and Conditions.
|
||||
If you do not agree with any part of these terms, you must not use our services.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="2. User Responsibilities">
|
||||
<Text style={styles.paragraph}>
|
||||
You are responsible for maintaining the confidentiality of your account information and
|
||||
for all activities that occur under your account. You agree to notify us immediately
|
||||
of any unauthorized use of your account.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="2. User Responsibilities"
|
||||
icon={<Users size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={1}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
You are responsible for maintaining the confidentiality of your account information and
|
||||
for all activities that occur under your account. You agree to notify us immediately
|
||||
of any unauthorized use of your account.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="3. Intellectual Property">
|
||||
<Text style={styles.paragraph}>
|
||||
All content included on our platform, such as text, graphics, logos, and software, is
|
||||
the property of our company and protected by intellectual property laws. You may not
|
||||
reproduce, distribute, or create derivative works without our express permission.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="3. Intellectual Property"
|
||||
icon={<Brain size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={2}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
All content included on our platform, such as text, graphics, logos, and software, is
|
||||
the property of our company and protected by intellectual property laws. You may not
|
||||
reproduce, distribute, or create derivative works without our express permission.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="4. Limitation of Liability">
|
||||
<Text style={styles.paragraph}>
|
||||
Our company shall not be liable for any indirect, incidental, special, or consequential
|
||||
damages resulting from the use or inability to use our services, even if we have been
|
||||
advised of the possibility of such damages.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="4. Limitation of Liability"
|
||||
icon={<Shield size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={3}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
Our company shall not be liable for any indirect, incidental, special, or consequential
|
||||
damages resulting from the use or inability to use our services, even if we have been
|
||||
advised of the possibility of such damages.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="5. Privacy Policy">
|
||||
<Text style={styles.paragraph}>
|
||||
Your use of our services is also governed by our Privacy Policy, which explains how we
|
||||
collect, use, and protect your personal information. Please review our Privacy Policy
|
||||
to understand our practices.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="5. Privacy Policy"
|
||||
icon={<Lock size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={4}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
Your use of our services is also governed by our Privacy Policy, which explains how we
|
||||
collect, use, and protect your personal information. Please review our Privacy Policy
|
||||
to understand our practices.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="6. Changes to Terms">
|
||||
<Text style={styles.paragraph}>
|
||||
We reserve the right to modify these terms at any time. We will notify you of any changes
|
||||
by posting the new Terms and Conditions on this page. Your continued use of the service
|
||||
after such modifications constitutes your acceptance of the new terms.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="6. Changes to Terms"
|
||||
icon={<RefreshCw size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={5}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
We reserve the right to modify these terms at any time. We will notify you of any changes
|
||||
by posting the new Terms and Conditions on this page. Your continued use of the service
|
||||
after such modifications constitutes your acceptance of the new terms.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Section title="7. Governing Law">
|
||||
<Text style={styles.paragraph}>
|
||||
These Terms shall be governed by and construed in accordance with the laws of the
|
||||
jurisdiction in which our company is registered, without regard to its conflict of law provisions.
|
||||
</Text>
|
||||
</Section>
|
||||
<Section
|
||||
title="7. Governing Law"
|
||||
icon={<Scale size={18} color={colors.primary} />}
|
||||
styles={styles}
|
||||
colors={colors}
|
||||
spacing={spacing}
|
||||
index={6}
|
||||
>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} style={styles.paragraph}>
|
||||
These Terms shall be governed by and construed in accordance with the laws of the
|
||||
jurisdiction in which our company is registered, without regard to its conflict of law provisions.
|
||||
</AppText>
|
||||
</Section>
|
||||
|
||||
<Text style={styles.footerText}>
|
||||
<Animated.View entering={FadeInUp.delay(500).springify()}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.footerText}>
|
||||
If you have any questions about these Terms, please contact us at legal@company.com.
|
||||
</Text>
|
||||
</View>
|
||||
</AppText>
|
||||
</Animated.View>
|
||||
|
||||
{/* Accept Button */}
|
||||
<TouchableOpacity
|
||||
{/* Spacer for button */}
|
||||
<View style={{ height: 100 }} />
|
||||
</ScrollView>
|
||||
|
||||
{/* ═══ Accept Button ═══ */}
|
||||
<Animated.View
|
||||
entering={FadeInDown.delay(300).springify()}
|
||||
style={styles.acceptButtonWrapper}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={styles.acceptButton}
|
||||
onPress={() => {
|
||||
onClose();
|
||||
onChecked();
|
||||
}}
|
||||
activeOpacity={0.85}
|
||||
>
|
||||
<CheckCircle color={colors.white} size={28} />
|
||||
<Text style={styles.acceptButtonText}>I Accept</Text>
|
||||
<CheckCircle color={colors.buttonText} size={22} strokeWidth={2.5} />
|
||||
<AppText variant="button" color={colors.buttonText} style={{ marginLeft: 10 }}>
|
||||
I Accept
|
||||
</AppText>
|
||||
</TouchableOpacity>
|
||||
</ScrollView>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
// Reusable Section component
|
||||
|
||||
// ── Section sub-component ─────────────────────────────────────────────
|
||||
type SectionProps = {
|
||||
title: string;
|
||||
icon: ReactNode;
|
||||
children: ReactNode;
|
||||
styles: any;
|
||||
colors: any;
|
||||
spacing: any;
|
||||
index: number;
|
||||
};
|
||||
|
||||
const Section: React.FC<SectionProps> = ({ title, children }) => (
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{title}</Text>
|
||||
const Section: React.FC<SectionProps> = ({ title, icon, children, styles, colors, spacing, index }) => (
|
||||
<Animated.View
|
||||
entering={FadeInUp.delay(100 + index * 60).springify()}
|
||||
style={styles.section}
|
||||
>
|
||||
<View style={styles.sectionHeader}>
|
||||
{icon}
|
||||
<AppText variant="bodySmall" color={colors.text} style={styles.sectionTitle}>
|
||||
{title}
|
||||
</AppText>
|
||||
</View>
|
||||
{children}
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
export default TermsAndConditionsModal;
|
||||
|
||||
|
||||
// ── Styles ────────────────────────────────────────────────────────────
|
||||
const makeStyles = (colors: any, spacing: any, shadows: any, typography: any) => StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.lightGray, // Updated with your colors
|
||||
},
|
||||
scrollContainer: {
|
||||
paddingBottom: 120, // Space for accept button
|
||||
flexGrow: 1,
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
header: {
|
||||
backgroundColor: colors.primary, // Orange header
|
||||
paddingVertical: 32,
|
||||
paddingHorizontal: 24,
|
||||
borderBottomLeftRadius: 24,
|
||||
borderBottomRightRadius: 24,
|
||||
marginBottom: 24,
|
||||
shadowColor: colors.shadow,
|
||||
shadowOffset: { width: 0, height: 6 },
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 12,
|
||||
elevation: 8,
|
||||
backgroundColor: colors.primary,
|
||||
paddingTop: spacing.xl,
|
||||
paddingBottom: spacing.l,
|
||||
paddingHorizontal: spacing.l,
|
||||
borderBottomLeftRadius: 20,
|
||||
borderBottomRightRadius: 20,
|
||||
},
|
||||
title: {
|
||||
fontSize: 28,
|
||||
fontWeight: '800',
|
||||
color: colors.white,
|
||||
marginBottom: 4,
|
||||
headerRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 14,
|
||||
color: 'rgba(255,255,255,0.85)',
|
||||
closeButton: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
backgroundColor: 'rgba(255,255,255,0.2)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
content: {
|
||||
paddingHorizontal: 24,
|
||||
scrollContainer: {
|
||||
padding: spacing.l,
|
||||
paddingBottom: 40,
|
||||
},
|
||||
section: {
|
||||
marginBottom: 28,
|
||||
backgroundColor: colors.surface,
|
||||
borderRadius: 14,
|
||||
padding: spacing.m,
|
||||
marginBottom: spacing.m,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
sectionHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
marginBottom: spacing.s,
|
||||
paddingBottom: spacing.s,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: '700',
|
||||
color: colors.darkText,
|
||||
marginBottom: 12,
|
||||
fontSize: typography.size.s,
|
||||
},
|
||||
paragraph: {
|
||||
fontSize: 16,
|
||||
lineHeight: 25,
|
||||
color: colors.grayText,
|
||||
},
|
||||
footerText: {
|
||||
fontSize: 15,
|
||||
fontStyle: 'italic',
|
||||
color: colors.lightText,
|
||||
marginTop: 24,
|
||||
textAlign: 'center',
|
||||
lineHeight: 22,
|
||||
},
|
||||
acceptButton: {
|
||||
footerText: {
|
||||
fontStyle: 'italic',
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
marginTop: spacing.m,
|
||||
},
|
||||
acceptButtonWrapper: {
|
||||
position: 'absolute',
|
||||
bottom: 40,
|
||||
left: 24,
|
||||
right: 24,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
padding: spacing.m,
|
||||
paddingBottom: spacing.xl,
|
||||
backgroundColor: colors.surface,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.border,
|
||||
},
|
||||
acceptButton: {
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 16,
|
||||
borderRadius: 14,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 18,
|
||||
paddingHorizontal: 20,
|
||||
shadowColor: colors.shadow,
|
||||
shadowOffset: { width: 0, height: 8 },
|
||||
shadowOpacity: 0.35,
|
||||
shadowRadius: 16,
|
||||
elevation: 12,
|
||||
},
|
||||
acceptButtonText: {
|
||||
color: colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
marginLeft: 12,
|
||||
letterSpacing: 0.5,
|
||||
paddingVertical: 16,
|
||||
},
|
||||
});
|
||||
|
||||
export default TermsAndConditionsModal;
|
||||
|
||||
Reference in New Issue
Block a user