huhuih
hzgjuigik
This commit is contained in:
226
client/src/components/PrivacySecurity.tsx
Normal file
226
client/src/components/PrivacySecurity.tsx
Normal file
@@ -0,0 +1,226 @@
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'
|
||||
import { Shield, Lock, Trash2, X, Check, AlertTriangle } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
|
||||
interface PrivacySecurityProps {
|
||||
onDisconnect?: (accountId: string) => void
|
||||
onDeleteAccount?: () => void
|
||||
connectedAccounts?: Array<{ id: string; email: string; provider: string }>
|
||||
}
|
||||
|
||||
export function PrivacySecurity({ onDisconnect, onDeleteAccount, connectedAccounts = [] }: PrivacySecurityProps) {
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* What data is accessed */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Shield className="w-5 h-5 text-primary-500" />
|
||||
What data is accessed
|
||||
</CardTitle>
|
||||
<CardDescription>We only access what's necessary for sorting</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div className="flex items-start gap-3 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
|
||||
<Check className="w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-green-900 dark:text-green-100">Email headers and metadata</p>
|
||||
<p className="text-sm text-green-700 dark:text-green-300 mt-1">
|
||||
We read: sender, subject, date, labels/categories. This is all we need to categorize emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
|
||||
<Check className="w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-green-900 dark:text-green-100">Email preview/snippet</p>
|
||||
<p className="text-sm text-green-700 dark:text-green-300 mt-1">
|
||||
We read the first few lines to help AI understand the email content.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* What is stored */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Lock className="w-5 h-5 text-primary-500 dark:text-primary-400" />
|
||||
What is stored
|
||||
</CardTitle>
|
||||
<CardDescription>Your data stays secure</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div className="flex items-start gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
||||
<Check className="w-5 h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-blue-900 dark:text-blue-100">Your preferences</p>
|
||||
<p className="text-sm text-blue-700 dark:text-blue-300 mt-1">
|
||||
VIP senders, category settings, company labels, sorting rules.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
||||
<Check className="w-5 h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-blue-900 dark:text-blue-100">Statistics</p>
|
||||
<p className="text-sm text-blue-700 dark:text-blue-300 mt-1">
|
||||
Counts of sorted emails, categories, time saved. No email content.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
||||
<Check className="w-5 h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-blue-900 dark:text-blue-100">Account connection tokens</p>
|
||||
<p className="text-sm text-blue-700 dark:text-blue-300 mt-1">
|
||||
Encrypted OAuth tokens to access your email (required for sorting).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* What is never stored */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<X className="w-5 h-5 text-red-500 dark:text-red-400" />
|
||||
What is never stored
|
||||
</CardTitle>
|
||||
<CardDescription>Your privacy is protected</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div className="flex items-start gap-3 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
|
||||
<X className="w-5 h-5 text-red-600 dark:text-red-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-red-900 dark:text-red-100">Email bodies/content</p>
|
||||
<p className="text-sm text-red-700 dark:text-red-300 mt-1">
|
||||
We never store the full content of your emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
|
||||
<X className="w-5 h-5 text-red-600 dark:text-red-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-red-900 dark:text-red-100">Attachments</p>
|
||||
<p className="text-sm text-red-700 dark:text-red-300 mt-1">
|
||||
We never access or store file attachments.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
|
||||
<X className="w-5 h-5 text-red-600 dark:text-red-400 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium text-red-900 dark:text-red-100">Passwords</p>
|
||||
<p className="text-sm text-red-700 dark:text-red-300 mt-1">
|
||||
We use OAuth - we never see or store your email passwords.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* How to disconnect */}
|
||||
{connectedAccounts.length > 0 && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Disconnect email accounts</CardTitle>
|
||||
<CardDescription>Remove access to your email accounts</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
{connectedAccounts.map((account) => (
|
||||
<div key={account.id} className="flex items-center justify-between p-4 border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-800">
|
||||
<div>
|
||||
<p className="font-medium text-slate-900 dark:text-slate-100">{account.email}</p>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400 capitalize">{account.provider}</p>
|
||||
</div>
|
||||
{onDisconnect && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onDisconnect(account.id)}
|
||||
className="text-red-600 dark:text-red-400 border-red-200 dark:border-red-800 hover:bg-red-50 dark:hover:bg-red-900/20"
|
||||
>
|
||||
Disconnect
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Delete account */}
|
||||
{onDeleteAccount && (
|
||||
<Card className="border-red-200 dark:border-red-800">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-red-600 dark:text-red-400">
|
||||
<Trash2 className="w-5 h-5" />
|
||||
Delete my data
|
||||
</CardTitle>
|
||||
<CardDescription>Permanently delete all your data and account</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{!showDeleteConfirm ? (
|
||||
<div className="space-y-3">
|
||||
<div className="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
|
||||
<p className="text-sm text-red-800 dark:text-red-200 mb-2">
|
||||
<AlertTriangle className="w-4 h-4 inline mr-1" />
|
||||
This action cannot be undone
|
||||
</p>
|
||||
<p className="text-xs text-red-700 dark:text-red-300">
|
||||
This will delete all your preferences, statistics, connected accounts, and subscription data.
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={() => setShowDeleteConfirm(true)}
|
||||
className="w-full bg-red-600 hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-800 text-white"
|
||||
>
|
||||
<Trash2 className="w-4 h-4 mr-2" />
|
||||
Delete my account and data
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
<div className="p-4 bg-red-100 dark:bg-red-900/30 border-2 border-red-300 dark:border-red-700 rounded-lg">
|
||||
<p className="font-semibold text-red-900 dark:text-red-100 mb-2">Are you absolutely sure?</p>
|
||||
<p className="text-sm text-red-800 dark:text-red-200">
|
||||
This will permanently delete:
|
||||
</p>
|
||||
<ul className="text-sm text-red-700 dark:text-red-300 mt-2 space-y-1 list-disc list-inside">
|
||||
<li>All your email account connections</li>
|
||||
<li>All sorting statistics</li>
|
||||
<li>All preferences and settings</li>
|
||||
<li>Your subscription (if active)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={onDeleteAccount}
|
||||
className="flex-1 bg-red-600 hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-800 text-white"
|
||||
>
|
||||
Yes, delete everything
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowDeleteConfirm(false)}
|
||||
className="flex-1"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user