Files
carry-your-live/carry-your-live/src/components/LegalModal.tsx
T

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,
},
});