202 lines
5.7 KiB
TypeScript
202 lines
5.7 KiB
TypeScript
import React from 'react';
|
|
import { View, Text, StyleSheet, SafeAreaView, ScrollView, TouchableOpacity } from 'react-native';
|
|
import Svg, { Path } from 'react-native-svg';
|
|
import { useSettings } from '@/theme';
|
|
|
|
interface LegalModalProps {
|
|
visible: boolean;
|
|
type: 'privacy' | 'terms' | null;
|
|
onClose: () => void;
|
|
}
|
|
|
|
const PRIVACY_POLICY = `
|
|
Privacy Policy for Carry Your Live
|
|
|
|
Last updated: ${new Date().toLocaleDateString()}
|
|
|
|
1. Information We Collect
|
|
|
|
We collect information you provide directly to us, such as when you create an account, add tasks, or interact with other users.
|
|
|
|
- Account Information: Username and password (securely hashed)
|
|
- Task Data: Tasks, subtasks, categories, due dates, reminders, and related metadata
|
|
- Social Data: Friend requests, accepted friendships, and assigned tasks
|
|
- Usage Data: App interactions, sync timestamps, and error logs
|
|
|
|
2. How We Use Your Information
|
|
|
|
- Provide and maintain the service
|
|
- Sync your data across devices
|
|
- Enable social features (friend requests, task assignment)
|
|
- Send notifications (with your permission)
|
|
- Improve the app experience
|
|
|
|
3. Data Storage & Security
|
|
|
|
- Passwords are hashed using bcrypt (never stored in plain text)
|
|
- Data is stored locally on your device using SQLite
|
|
- Optional cloud sync uses encrypted HTTPS connections
|
|
- You can delete your account and all data at any time
|
|
|
|
4. Data Sharing
|
|
|
|
We do not sell your personal information. Data is shared only:
|
|
- With friends you explicitly connect with (task assignments, shared lists)
|
|
- With our backend service for sync functionality
|
|
- When required by law
|
|
|
|
5. Your Rights
|
|
|
|
- Access: View all data associated with your account
|
|
- Rectification: Correct inaccurate data
|
|
- Erasure: Delete your account and all data
|
|
- Portability: Export your data (via sync)
|
|
- Restrict Processing: Disable sync or notifications
|
|
|
|
6. Children's Privacy
|
|
|
|
This app is not intended for users under 13. We do not knowingly collect data from children under 13.
|
|
|
|
7. Changes to This Policy
|
|
|
|
We may update this policy. Continued use constitutes acceptance.
|
|
|
|
8. Contact
|
|
|
|
For privacy questions, contact us through the app's feedback channel.
|
|
`;
|
|
|
|
const TERMS_OF_SERVICE = `
|
|
Terms of Service for Carry Your Live
|
|
|
|
Last updated: ${new Date().toLocaleDateString()}
|
|
|
|
1. Acceptance of Terms
|
|
|
|
By using Carry Your Live, you agree to these Terms. If you disagree, do not use the app.
|
|
|
|
2. Account Registration
|
|
|
|
- You must provide accurate information
|
|
- You are responsible for your password security
|
|
- One account per person
|
|
- You must be 13+ years old
|
|
|
|
3. User Content
|
|
|
|
You retain ownership of your tasks, categories, and data. You grant us a license to store, sync, and display your content as needed to provide the service.
|
|
|
|
4. Social Features
|
|
|
|
- Friend requests require mutual acceptance
|
|
- You can remove friends at any time
|
|
- Assigned tasks are visible to both parties
|
|
- Harassment or abuse will result in account termination
|
|
|
|
5. Service Availability
|
|
|
|
We strive for high availability but do not guarantee 100% uptime. The service may be temporarily unavailable for maintenance.
|
|
|
|
6. Disclaimers
|
|
|
|
THE SERVICE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY KIND. WE DO NOT GUARANTEE THAT THE SERVICE WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE.
|
|
|
|
7. Limitation of Liability
|
|
|
|
TO THE MAXIMUM EXTENT PERMITTED BY LAW, WE ARE NOT LIABLE FOR INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES.
|
|
|
|
8. Termination
|
|
|
|
You may delete your account at any time. We may terminate accounts that violate these Terms.
|
|
|
|
9. Governing Law
|
|
|
|
These Terms are governed by the laws of your country of residence.
|
|
|
|
10. Changes
|
|
|
|
We may modify these Terms. Continued use after changes constitutes acceptance.
|
|
|
|
11. Contact
|
|
|
|
For questions about these Terms, contact us through the app's feedback channel.
|
|
`;
|
|
|
|
export function LegalModal({ visible, type, onClose }: LegalModalProps) {
|
|
const { theme } = useSettings();
|
|
const content = type === 'privacy' ? PRIVACY_POLICY : TERMS_OF_SERVICE;
|
|
const title = type === 'privacy' ? 'Privacy Policy' : 'Terms of Service';
|
|
|
|
if (!visible || !type) return null;
|
|
|
|
return (
|
|
<SafeAreaView style={[styles.overlay, { backgroundColor: theme.overlay }]}>
|
|
<View style={[styles.modal, { backgroundColor: theme.card }]}>
|
|
<View style={[styles.header, { borderBottomColor: theme.border }]}>
|
|
<Text style={[styles.title, { color: theme.text }]}>{title}</Text>
|
|
<TouchableOpacity onPress={onClose} style={styles.closeButton} activeOpacity={0.7}>
|
|
<Svg width={24} height={24} viewBox="0 0 24 24">
|
|
<Path
|
|
d="M18 6L6 18M6 6l12 12"
|
|
stroke={theme.textSecondary}
|
|
strokeWidth={2.2}
|
|
strokeLinecap="round"
|
|
/>
|
|
</Svg>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}>
|
|
<Text style={[styles.body, { color: theme.text }]}>{content}</Text>
|
|
</ScrollView>
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
overlay: {
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
justifyContent: 'center',
|
|
padding: 16,
|
|
zIndex: 100,
|
|
},
|
|
modal: {
|
|
borderRadius: 20,
|
|
maxHeight: '90%',
|
|
overflow: 'hidden',
|
|
},
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
paddingHorizontal: 20,
|
|
paddingVertical: 16,
|
|
borderBottomWidth: 1,
|
|
},
|
|
title: {
|
|
fontSize: 18,
|
|
fontWeight: '700',
|
|
flex: 1,
|
|
textAlign: 'center',
|
|
marginRight: 24,
|
|
},
|
|
closeButton: {
|
|
width: 40,
|
|
height: 40,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
content: {
|
|
padding: 20,
|
|
maxHeight: '70%',
|
|
},
|
|
body: {
|
|
fontSize: 14,
|
|
lineHeight: 22,
|
|
},
|
|
});
|