chore: Docs umstrukturiert, Client-Updates, Scripts nach scripts/
This commit is contained in:
@@ -29,22 +29,22 @@ export function ForgotPassword() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center p-4">
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-md">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center justify-center gap-2 mb-8">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center">
|
||||
<Mail className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-xl font-bold text-slate-900">
|
||||
Email<span className="text-primary-600">Sorter</span>
|
||||
<span className="text-xl font-bold text-slate-900 dark:text-slate-100">
|
||||
Email<span className="text-primary-600 dark:text-primary-400">Sorter</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<Card className="shadow-xl border-0">
|
||||
<Card className="shadow-xl border-0 dark:bg-slate-800 dark:border-slate-700">
|
||||
<CardHeader className="text-center pb-2">
|
||||
<CardTitle className="text-2xl">Passwort vergessen?</CardTitle>
|
||||
<CardDescription>
|
||||
<CardTitle className="text-2xl dark:text-slate-100">Passwort vergessen?</CardTitle>
|
||||
<CardDescription className="dark:text-slate-400">
|
||||
{sent
|
||||
? 'Prüfe dein E-Mail-Postfach'
|
||||
: 'Gib deine E-Mail-Adresse ein und wir senden dir einen Link zum Zurücksetzen.'
|
||||
@@ -54,14 +54,14 @@ export function ForgotPassword() {
|
||||
<CardContent>
|
||||
{sent ? (
|
||||
<div className="text-center py-8">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-green-100 flex items-center justify-center">
|
||||
<CheckCircle className="w-8 h-8 text-green-600" />
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
|
||||
<CheckCircle className="w-8 h-8 text-green-600 dark:text-green-400" />
|
||||
</div>
|
||||
<h3 className="font-semibold text-slate-900 mb-2">E-Mail gesendet!</h3>
|
||||
<p className="text-slate-600 mb-6">
|
||||
Wir haben dir eine E-Mail mit einem Link zum Zurücksetzen deines Passworts an <strong>{email}</strong> gesendet.
|
||||
<h3 className="font-semibold text-slate-900 dark:text-slate-100 mb-2">E-Mail gesendet!</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-6">
|
||||
Wir haben dir eine E-Mail mit einem Link zum Zurücksetzen deines Passworts an <strong className="text-slate-900 dark:text-slate-100">{email}</strong> gesendet.
|
||||
</p>
|
||||
<p className="text-sm text-slate-500 mb-6">
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400 mb-6">
|
||||
Keine E-Mail erhalten? Prüfe deinen Spam-Ordner oder versuche es erneut.
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
@@ -83,13 +83,13 @@ export function ForgotPassword() {
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{error && (
|
||||
<div className="p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">
|
||||
<div className="p-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg text-red-700 dark:text-red-300 text-sm">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">E-Mail-Adresse</Label>
|
||||
<Label htmlFor="email" className="dark:text-slate-200">E-Mail-Adresse</Label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
@@ -98,6 +98,7 @@ export function ForgotPassword() {
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
autoFocus
|
||||
className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -115,7 +116,7 @@ export function ForgotPassword() {
|
||||
<div className="text-center">
|
||||
<Link
|
||||
to="/login"
|
||||
className="text-sm text-primary-600 hover:text-primary-700"
|
||||
className="text-sm text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 inline mr-1" />
|
||||
Zurück zum Login
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ArrowLeft, Building2 } from 'lucide-react'
|
||||
|
||||
export function Imprint() {
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50">
|
||||
<div className="min-h-screen bg-slate-50 dark:bg-slate-900">
|
||||
{/* Header */}
|
||||
<header className="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-700">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
@@ -19,56 +19,56 @@ export function Imprint() {
|
||||
|
||||
{/* Content */}
|
||||
<main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-8 md:p-12">
|
||||
<div className="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-slate-200 dark:border-slate-700 p-8 md:p-12">
|
||||
{/* Title */}
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary-100 flex items-center justify-center">
|
||||
<Building2 className="w-6 h-6 text-primary-600" />
|
||||
<div className="w-12 h-12 rounded-lg bg-primary-100 dark:bg-primary-900/30 flex items-center justify-center">
|
||||
<Building2 className="w-6 h-6 text-primary-600 dark:text-primary-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-slate-900">Impressum</h1>
|
||||
<p className="text-slate-500 mt-1">Legal Information</p>
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100">Impressum</h1>
|
||||
<p className="text-slate-500 dark:text-slate-400 mt-1">Legal Information</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content - Placeholder for webklar.com content */}
|
||||
<div className="prose prose-slate max-w-none">
|
||||
<p className="text-slate-600 mb-6">
|
||||
<div className="prose prose-slate max-w-none dark:prose-invert">
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-6">
|
||||
<strong>Note:</strong> This imprint is managed by webklar.com. Please refer to their imprint for detailed information.
|
||||
</p>
|
||||
|
||||
<div className="bg-slate-50 border border-slate-200 rounded-lg p-6 mb-8">
|
||||
<h2 className="text-xl font-semibold text-slate-900 mb-4">Information according to § 5 TMG</h2>
|
||||
<div className="bg-slate-50 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-6 mb-8">
|
||||
<h2 className="text-xl font-semibold text-slate-900 dark:text-slate-100 mb-4">Information according to § 5 TMG</h2>
|
||||
|
||||
<div className="space-y-6 text-slate-700">
|
||||
<div className="space-y-6 text-slate-700 dark:text-slate-300">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-slate-900 mb-2">Operator</h3>
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-2">Operator</h3>
|
||||
<p className="mb-2">EmailSorter is operated by:</p>
|
||||
<p className="mb-4">
|
||||
<strong>webklar.com</strong><br />
|
||||
Kenso Grimm, Justin Klein
|
||||
</p>
|
||||
<p className="text-sm text-slate-600 mb-4">
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400 mb-4">
|
||||
For complete contact details and legal information, please visit:{' '}
|
||||
<a
|
||||
href="https://webklar.com/impressum"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
webklar.com/impressum
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="pt-6 border-t border-slate-200">
|
||||
<h3 className="text-lg font-semibold text-slate-900 mb-2">Contact</h3>
|
||||
<div className="pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-2">Contact</h3>
|
||||
<div className="space-y-2">
|
||||
<p>
|
||||
<strong>Email:</strong>{' '}
|
||||
<a
|
||||
href="mailto:support@webklar.com"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
support@webklar.com
|
||||
</a>
|
||||
@@ -77,23 +77,23 @@ export function Imprint() {
|
||||
<strong>Phone:</strong>{' '}
|
||||
<a
|
||||
href="tel:+4917623726355"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
+49 176 23726355
|
||||
</a>
|
||||
{' / '}
|
||||
<a
|
||||
href="tel:+491704969375"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
+49 170 4969375
|
||||
</a>
|
||||
</p>
|
||||
<p className="mt-4 text-sm text-slate-600">
|
||||
<p className="mt-4 text-sm text-slate-600 dark:text-slate-400">
|
||||
For questions regarding EmailSorter specifically:{' '}
|
||||
<a
|
||||
href="mailto:support@emailsorter.com"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
support@emailsorter.com
|
||||
</a>
|
||||
@@ -101,8 +101,8 @@ export function Imprint() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-6 border-t border-slate-200">
|
||||
<h3 className="text-lg font-semibold text-slate-900 mb-2">Responsible for Content</h3>
|
||||
<div className="pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-2">Responsible for Content</h3>
|
||||
<p>
|
||||
The content of this website is the responsibility of webklar.com.
|
||||
For detailed information, please refer to the official imprint at{' '}
|
||||
@@ -110,23 +110,23 @@ export function Imprint() {
|
||||
href="https://webklar.com/impressum"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
webklar.com/impressum
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="pt-6 border-t border-slate-200">
|
||||
<h3 className="text-lg font-semibold text-slate-900 mb-2">Liability for Links</h3>
|
||||
<div className="pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-2">Liability for Links</h3>
|
||||
<p>
|
||||
Our website contains links to external websites. We have no influence on the content of these websites.
|
||||
Therefore, we cannot assume any liability for these external contents.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="pt-6 border-t border-slate-200">
|
||||
<h3 className="text-lg font-semibold text-slate-900 mb-2">Copyright</h3>
|
||||
<div className="pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-2">Copyright</h3>
|
||||
<p>
|
||||
The content and works on this website are subject to German copyright law.
|
||||
Reproduction, processing, distribution, and any form of commercialization require the written consent of the respective author or creator.
|
||||
@@ -134,14 +134,14 @@ export function Imprint() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-slate-200">
|
||||
<p className="text-sm text-slate-500">
|
||||
<div className="mt-8 pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">
|
||||
<strong>Important:</strong> This is a simplified version. For the complete and legally binding imprint, please visit{' '}
|
||||
<a
|
||||
href="https://webklar.com/impressum"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary-600 hover:text-primary-700 underline"
|
||||
className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline"
|
||||
>
|
||||
webklar.com/impressum
|
||||
</a>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ArrowLeft, Shield } from 'lucide-react'
|
||||
|
||||
export function Privacy() {
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50">
|
||||
<div className="min-h-screen bg-slate-50 dark:bg-slate-900">
|
||||
{/* Header */}
|
||||
<header className="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-700">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
@@ -19,81 +19,81 @@ export function Privacy() {
|
||||
|
||||
{/* Content */}
|
||||
<main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-8 md:p-12">
|
||||
<div className="bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-slate-200 dark:border-slate-700 p-8 md:p-12">
|
||||
{/* Title */}
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary-100 flex items-center justify-center">
|
||||
<Shield className="w-6 h-6 text-primary-600" />
|
||||
<div className="w-12 h-12 rounded-lg bg-primary-100 dark:bg-primary-900/30 flex items-center justify-center">
|
||||
<Shield className="w-6 h-6 text-primary-600 dark:text-primary-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-slate-900">Privacy Policy</h1>
|
||||
<p className="text-slate-500 mt-1">Last updated: {new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}</p>
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100">Privacy Policy</h1>
|
||||
<p className="text-slate-500 dark:text-slate-400 mt-1">Last updated: {new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content - Placeholder for webklar.com content */}
|
||||
<div className="prose prose-slate max-w-none">
|
||||
<p className="text-slate-600 mb-6">
|
||||
<div className="prose prose-slate max-w-none dark:prose-invert">
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-6">
|
||||
<strong>Note:</strong> This privacy policy is managed by webklar.com. Please refer to their privacy policy for detailed information.
|
||||
</p>
|
||||
|
||||
<div className="bg-slate-50 border border-slate-200 rounded-lg p-6 mb-8">
|
||||
<h2 className="text-xl font-semibold text-slate-900 mb-4">Data Protection Information</h2>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<div className="bg-slate-50 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-6 mb-8">
|
||||
<h2 className="text-xl font-semibold text-slate-900 dark:text-slate-100 mb-4">Data Protection Information</h2>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
EmailSorter is operated by webklar.com. The following privacy policy applies to the use of this website and our services.
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">1. Responsible Party</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">1. Responsible Party</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
The responsible party for data processing on this website is:
|
||||
</p>
|
||||
<div className="bg-white border border-slate-200 rounded-lg p-4 mb-4">
|
||||
<p className="text-slate-700 mb-2">
|
||||
<div className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg p-4 mb-4">
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-2">
|
||||
<strong>webklar.com</strong><br />
|
||||
Kenso Grimm, Justin Klein
|
||||
</p>
|
||||
<p className="text-slate-700 mb-2">
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-2">
|
||||
<strong>Contact:</strong><br />
|
||||
Email: <a href="mailto:support@webklar.com" className="text-primary-600 hover:text-primary-700 underline">support@webklar.com</a><br />
|
||||
Phone: <a href="tel:+4917623726355" className="text-primary-600 hover:text-primary-700 underline">+49 176 23726355</a>
|
||||
Email: <a href="mailto:support@webklar.com" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">support@webklar.com</a><br />
|
||||
Phone: <a href="tel:+4917623726355" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">+49 176 23726355</a>
|
||||
</p>
|
||||
<p className="text-sm text-slate-600 mt-3">
|
||||
For complete contact details, please refer to the <Link to="/imprint" className="text-primary-600 hover:text-primary-700 underline">Impressum</Link>.
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400 mt-3">
|
||||
For complete contact details, please refer to the <Link to="/imprint" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">Impressum</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">2. Data Collection and Processing</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">2. Data Collection and Processing</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
When you use EmailSorter, we collect and process the following data:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-slate-700 mb-4 space-y-2 ml-4">
|
||||
<ul className="list-disc list-inside text-slate-700 dark:text-slate-300 mb-4 space-y-2 ml-4">
|
||||
<li>Account information (email address, name)</li>
|
||||
<li>Email metadata (sender, subject, date) for sorting purposes</li>
|
||||
<li>Usage statistics and preferences</li>
|
||||
<li>Payment information (processed securely via Stripe)</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">3. Purpose of Data Processing</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">3. Purpose of Data Processing</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
We process your data exclusively for the following purposes:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-slate-700 mb-4 space-y-2 ml-4">
|
||||
<ul className="list-disc list-inside text-slate-700 dark:text-slate-300 mb-4 space-y-2 ml-4">
|
||||
<li>Providing and improving the EmailSorter service</li>
|
||||
<li>Automated email sorting and categorization</li>
|
||||
<li>Processing payments and subscriptions</li>
|
||||
<li>Customer support and communication</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">4. Data Security</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">4. Data Security</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
We implement appropriate technical and organizational measures to protect your data against unauthorized access, loss, or destruction.
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">5. Your Rights</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">5. Your Rights</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
You have the right to:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-slate-700 mb-4 space-y-2 ml-4">
|
||||
<ul className="list-disc list-inside text-slate-700 dark:text-slate-300 mb-4 space-y-2 ml-4">
|
||||
<li>Access your personal data</li>
|
||||
<li>Correct inaccurate data</li>
|
||||
<li>Request deletion of your data</li>
|
||||
@@ -101,14 +101,14 @@ export function Privacy() {
|
||||
<li>Data portability</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">6. Hosting and Third-Party Services</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">6. Hosting and Third-Party Services</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
<strong>Hosting:</strong> Our website is hosted by Netlify, which acts as a data processor.
|
||||
</p>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
We use the following third-party services:
|
||||
</p>
|
||||
<ul className="list-disc list-inside text-slate-700 mb-4 space-y-2 ml-4">
|
||||
<ul className="list-disc list-inside text-slate-700 dark:text-slate-300 mb-4 space-y-2 ml-4">
|
||||
<li><strong>Appwrite:</strong> User authentication and database</li>
|
||||
<li><strong>Stripe:</strong> Payment processing</li>
|
||||
<li><strong>Mistral AI:</strong> Email categorization</li>
|
||||
@@ -116,45 +116,45 @@ export function Privacy() {
|
||||
<li><strong>Plausible (optional):</strong> Privacy-friendly analytics tool, if enabled</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">6.1. Cookies and Tracking</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">6.1. Cookies and Tracking</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
We do not use external fonts or unnecessary cookies. If we use any tracking tools (such as Plausible),
|
||||
they are privacy-friendly and do not store personal data. We only process personal data to the extent
|
||||
that it is technically or organizationally necessary.
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">7. Contact Form Data</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">7. Contact Form Data</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
Data that you send to us via contact forms will be stored and used for processing your inquiry.
|
||||
This data will not be shared with third parties without your consent.
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-slate-900 mt-6 mb-3">8. Contact</h3>
|
||||
<p className="text-slate-700 mb-4">
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mt-6 mb-3">8. Contact</h3>
|
||||
<p className="text-slate-700 dark:text-slate-300 mb-4">
|
||||
For questions regarding data protection, please contact us:
|
||||
</p>
|
||||
<div className="bg-white border border-slate-200 rounded-lg p-4 mb-4">
|
||||
<p className="text-slate-700">
|
||||
<div className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg p-4 mb-4">
|
||||
<p className="text-slate-700 dark:text-slate-300">
|
||||
<strong>Email:</strong>{' '}
|
||||
<a href="mailto:support@webklar.com" className="text-primary-600 hover:text-primary-700 underline">
|
||||
<a href="mailto:support@webklar.com" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">
|
||||
support@webklar.com
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-slate-700 mt-2">
|
||||
<p className="text-slate-700 dark:text-slate-300 mt-2">
|
||||
<strong>Phone:</strong>{' '}
|
||||
<a href="tel:+4917623726355" className="text-primary-600 hover:text-primary-700 underline">
|
||||
<a href="tel:+4917623726355" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">
|
||||
+49 176 23726355
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-sm text-slate-600 mt-3">
|
||||
For complete contact details, please refer to the <Link to="/imprint" className="text-primary-600 hover:text-primary-700 underline">Impressum</Link>.
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400 mt-3">
|
||||
For complete contact details, please refer to the <Link to="/imprint" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">Impressum</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-slate-200">
|
||||
<p className="text-sm text-slate-500">
|
||||
<div className="mt-8 pt-6 border-t border-slate-200 dark:border-slate-700">
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">
|
||||
<strong>Important:</strong> This is a simplified version. For the complete and legally binding privacy policy, please visit{' '}
|
||||
<a href="https://webklar.com/datenschutz" target="_blank" rel="noopener noreferrer" className="text-primary-600 hover:text-primary-700 underline">
|
||||
<a href="https://webklar.com/datenschutz" target="_blank" rel="noopener noreferrer" className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline">
|
||||
webklar.com/datenschutz
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -114,30 +114,30 @@ export function Register() {
|
||||
</div>
|
||||
|
||||
{/* Right side - Form */}
|
||||
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 bg-white">
|
||||
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 bg-white dark:bg-slate-900">
|
||||
<div className="w-full max-w-md">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center gap-2 mb-8">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center">
|
||||
<Mail className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-xl font-bold text-slate-900">
|
||||
E-Mail-<span className="text-primary-600">Sorter</span>
|
||||
<span className="text-xl font-bold text-slate-900 dark:text-slate-100">
|
||||
E-Mail-<span className="text-primary-600 dark:text-primary-400">Sorter</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<h1 className="text-3xl font-bold text-slate-900 mb-2">
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100 mb-2">
|
||||
Create account
|
||||
</h1>
|
||||
<p className="text-slate-600 mb-8">
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-8">
|
||||
Ready to go in less than a minute.
|
||||
</p>
|
||||
|
||||
{/* Error message */}
|
||||
{error && (
|
||||
<div className="mb-6 p-4 bg-red-50 border border-red-200 rounded-xl flex items-start gap-3">
|
||||
<AlertCircle className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-red-600">{error}</p>
|
||||
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-xl flex items-start gap-3">
|
||||
<AlertCircle className="w-5 h-5 text-red-500 dark:text-red-400 flex-shrink-0 mt-0.5" />
|
||||
<p className="text-sm text-red-600 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -217,16 +217,16 @@ export function Register() {
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<p className="text-xs text-slate-500 text-center">
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400 text-center">
|
||||
By signing up, you agree to our{' '}
|
||||
<a href="#" className="text-primary-600 hover:underline">Terms of Service</a> and{' '}
|
||||
<a href="#" className="text-primary-600 hover:underline">Privacy Policy</a>.
|
||||
<a href="#" className="text-primary-600 dark:text-primary-400 hover:underline">Terms of Service</a> and{' '}
|
||||
<a href="#" className="text-primary-600 dark:text-primary-400 hover:underline">Privacy Policy</a>.
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<p className="mt-8 text-center text-slate-600">
|
||||
<p className="mt-8 text-center text-slate-600 dark:text-slate-400">
|
||||
Already have an account?{' '}
|
||||
<Link to="/login" className="text-primary-600 font-semibold hover:text-primary-700">
|
||||
<Link to="/login" className="text-primary-600 dark:text-primary-400 font-semibold hover:text-primary-700 dark:hover:text-primary-300">
|
||||
Sign in
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
@@ -83,24 +83,24 @@ export function ResetPassword() {
|
||||
const passwordStrength = getPasswordStrength()
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center p-4">
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-md">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center justify-center gap-2 mb-8">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center">
|
||||
<Mail className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-xl font-bold text-slate-900">
|
||||
Email<span className="text-primary-600">Sorter</span>
|
||||
<span className="text-xl font-bold text-slate-900 dark:text-slate-100">
|
||||
Email<span className="text-primary-600 dark:text-primary-400">Sorter</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<Card className="shadow-xl border-0">
|
||||
<Card className="shadow-xl border-0 dark:bg-slate-800 dark:border-slate-700">
|
||||
<CardHeader className="text-center pb-2">
|
||||
<CardTitle className="text-2xl">
|
||||
<CardTitle className="text-2xl dark:text-slate-100">
|
||||
{success ? 'Passwort geändert!' : 'Neues Passwort festlegen'}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<CardDescription className="dark:text-slate-400">
|
||||
{success
|
||||
? 'Dein Passwort wurde erfolgreich geändert.'
|
||||
: 'Wähle ein sicheres neues Passwort für deinen Account.'
|
||||
@@ -110,10 +110,10 @@ export function ResetPassword() {
|
||||
<CardContent>
|
||||
{success ? (
|
||||
<div className="text-center py-8">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-green-100 flex items-center justify-center">
|
||||
<CheckCircle className="w-8 h-8 text-green-600" />
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
|
||||
<CheckCircle className="w-8 h-8 text-green-600 dark:text-green-400" />
|
||||
</div>
|
||||
<p className="text-slate-600 mb-6">
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-6">
|
||||
Du kannst dich jetzt mit deinem neuen Passwort anmelden.
|
||||
</p>
|
||||
<Button onClick={() => navigate('/login')} className="w-full">
|
||||
@@ -122,11 +122,11 @@ export function ResetPassword() {
|
||||
</div>
|
||||
) : !userId || !secret ? (
|
||||
<div className="text-center py-8">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-red-100 flex items-center justify-center">
|
||||
<XCircle className="w-8 h-8 text-red-600" />
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">
|
||||
<XCircle className="w-8 h-8 text-red-600 dark:text-red-400" />
|
||||
</div>
|
||||
<h3 className="font-semibold text-slate-900 mb-2">Ungültiger Link</h3>
|
||||
<p className="text-slate-600 mb-6">
|
||||
<h3 className="font-semibold text-slate-900 dark:text-slate-100 mb-2">Ungültiger Link</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400 mb-6">
|
||||
Dieser Link zum Zurücksetzen des Passworts ist ungültig oder abgelaufen.
|
||||
</p>
|
||||
<Link to="/forgot-password">
|
||||
@@ -136,13 +136,13 @@ export function ResetPassword() {
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{error && (
|
||||
<div className="p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">
|
||||
<div className="p-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg text-red-700 dark:text-red-300 text-sm">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password">Neues Passwort</Label>
|
||||
<Label htmlFor="password" className="dark:text-slate-200">Neues Passwort</Label>
|
||||
<div className="relative">
|
||||
<Input
|
||||
id="password"
|
||||
@@ -152,11 +152,12 @@ export function ResetPassword() {
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
autoFocus
|
||||
className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600"
|
||||
className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 dark:text-slate-500 hover:text-slate-600 dark:hover:text-slate-300"
|
||||
>
|
||||
{showPassword ? <EyeOff className="w-5 h-5" /> : <Eye className="w-5 h-5" />}
|
||||
</button>
|
||||
@@ -172,13 +173,13 @@ export function ResetPassword() {
|
||||
className={`h-1 flex-1 rounded-full transition-colors ${
|
||||
level <= passwordStrength.strength
|
||||
? passwordStrength.color
|
||||
: 'bg-slate-200'
|
||||
: 'bg-slate-200 dark:bg-slate-700'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<p className={`text-xs ${
|
||||
passwordStrength.strength < 3 ? 'text-red-500' : 'text-green-600'
|
||||
passwordStrength.strength < 3 ? 'text-red-500 dark:text-red-400' : 'text-green-600 dark:text-green-400'
|
||||
}`}>
|
||||
{passwordStrength.label}
|
||||
</p>
|
||||
@@ -187,7 +188,7 @@ export function ResetPassword() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="confirmPassword">Passwort bestätigen</Label>
|
||||
<Label htmlFor="confirmPassword" className="dark:text-slate-200">Passwort bestätigen</Label>
|
||||
<Input
|
||||
id="confirmPassword"
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
@@ -195,9 +196,10 @@ export function ResetPassword() {
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
required
|
||||
className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100"
|
||||
/>
|
||||
{confirmPassword && password !== confirmPassword && (
|
||||
<p className="text-xs text-red-500">Passwörter stimmen nicht überein</p>
|
||||
<p className="text-xs text-red-500 dark:text-red-400">Passwörter stimmen nicht überein</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -283,17 +283,17 @@ export function Setup() {
|
||||
// Show loading while checking accounts
|
||||
if (checkingAccounts) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-white flex items-center justify-center">
|
||||
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-white dark:from-slate-900 dark:to-slate-800 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Loader2 className="w-8 h-8 animate-spin text-primary-600 mx-auto mb-4" />
|
||||
<p className="text-slate-600">Setting up your account...</p>
|
||||
<Loader2 className="w-8 h-8 animate-spin text-primary-600 dark:text-primary-400 mx-auto mb-4" />
|
||||
<p className="text-slate-600 dark:text-slate-400">Setting up your account...</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-white">
|
||||
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-white dark:from-slate-900 dark:to-slate-800">
|
||||
<header className="bg-white/80 dark:bg-slate-900/80 backdrop-blur-sm border-b border-slate-200 dark:border-slate-700 sticky top-0 z-40">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -315,13 +315,13 @@ export function Setup() {
|
||||
{/* Success message after checkout */}
|
||||
{isFromCheckout && (
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 pt-8">
|
||||
<div className="bg-green-50 border border-green-200 rounded-xl p-6 mb-6 flex items-start gap-4">
|
||||
<div className="w-10 h-10 rounded-full bg-green-500 flex items-center justify-center flex-shrink-0">
|
||||
<div className="bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 rounded-xl p-6 mb-6 flex items-start gap-4">
|
||||
<div className="w-10 h-10 rounded-full bg-green-500 dark:bg-green-600 flex items-center justify-center flex-shrink-0">
|
||||
<Check className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold text-green-900 mb-1">Payment successful!</h3>
|
||||
<p className="text-sm text-green-700">
|
||||
<h3 className="font-semibold text-green-900 dark:text-green-200 mb-1">Payment successful!</h3>
|
||||
<p className="text-sm text-green-700 dark:text-green-300">
|
||||
Your subscription is active. Let's connect your email account to get started.
|
||||
</p>
|
||||
</div>
|
||||
@@ -351,23 +351,23 @@ export function Setup() {
|
||||
<div
|
||||
className={`w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold transition-all duration-300 ${
|
||||
index < stepIndex
|
||||
? 'bg-green-500 text-white shadow-lg shadow-green-500/30'
|
||||
? 'bg-green-500 dark:bg-green-600 text-white shadow-lg shadow-green-500/30'
|
||||
: index === stepIndex
|
||||
? 'bg-primary-500 text-white ring-4 ring-primary-100 shadow-lg shadow-primary-500/30'
|
||||
: 'bg-slate-100 text-slate-400'
|
||||
? 'bg-primary-500 dark:bg-primary-600 text-white ring-4 ring-primary-100 dark:ring-primary-900/50 shadow-lg shadow-primary-500/30'
|
||||
: 'bg-slate-100 dark:bg-slate-700 text-slate-400 dark:text-slate-500'
|
||||
}`}
|
||||
>
|
||||
{index < stepIndex ? <Check className="w-5 h-5" /> : index + 1}
|
||||
</div>
|
||||
<p className={`mt-2 text-xs font-medium hidden sm:block transition-colors ${
|
||||
index <= stepIndex ? 'text-slate-900' : 'text-slate-400'
|
||||
index <= stepIndex ? 'text-slate-900 dark:text-slate-100' : 'text-slate-400 dark:text-slate-500'
|
||||
}`}>
|
||||
{step.title}
|
||||
</p>
|
||||
</div>
|
||||
{index < steps.length - 1 && (
|
||||
<div className={`w-16 sm:w-24 h-1 mx-2 rounded-full transition-colors duration-500 ${
|
||||
index < stepIndex ? 'bg-green-500' : 'bg-slate-200'
|
||||
index < stepIndex ? 'bg-green-500 dark:bg-green-600' : 'bg-slate-200 dark:bg-slate-700'
|
||||
}`} />
|
||||
)}
|
||||
</div>
|
||||
@@ -376,7 +376,7 @@ export function Setup() {
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="mb-6 p-4 bg-red-50 border border-red-200 rounded-xl flex items-center gap-3 text-red-700">
|
||||
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-xl flex items-center gap-3 text-red-700 dark:text-red-300">
|
||||
<AlertCircle className="w-5 h-5 flex-shrink-0" />
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
@@ -388,8 +388,8 @@ export function Setup() {
|
||||
<div className="w-24 h-24 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-primary-100 to-primary-200 flex items-center justify-center shadow-xl shadow-primary-500/10">
|
||||
<Link2 className="w-12 h-12 text-primary-600" />
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold text-slate-900 mb-3">Connect your email account</h1>
|
||||
<p className="text-lg text-slate-600 mb-10 max-w-md mx-auto">
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100 mb-3">Connect your email account</h1>
|
||||
<p className="text-lg text-slate-600 dark:text-slate-400 mb-10 max-w-md mx-auto">
|
||||
Choose your email provider. The connection is secure and your data stays private.
|
||||
</p>
|
||||
|
||||
@@ -416,10 +416,10 @@ export function Setup() {
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<div className="w-full border-t border-slate-300"></div>
|
||||
<div className="w-full border-t border-slate-300 dark:border-slate-600"></div>
|
||||
</div>
|
||||
<div className="relative flex justify-center text-sm">
|
||||
<span className="px-4 bg-white text-slate-500">Or connect your inbox</span>
|
||||
<span className="px-4 bg-white dark:bg-slate-800 text-slate-500 dark:text-slate-400">Or connect your inbox</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -427,12 +427,12 @@ export function Setup() {
|
||||
<button
|
||||
onClick={handleConnectGmail}
|
||||
disabled={connecting !== null}
|
||||
className="flex items-center gap-4 p-6 bg-white rounded-2xl border-2 border-slate-200 hover:border-red-300 hover:shadow-xl hover:shadow-red-500/10 transition-all text-left group disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="flex items-center gap-4 p-6 bg-white dark:bg-slate-800 rounded-2xl border-2 border-slate-200 dark:border-slate-700 hover:border-red-300 dark:hover:border-red-600 hover:shadow-xl hover:shadow-red-500/10 transition-all text-left group disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{connecting === 'gmail' ? (
|
||||
<Loader2 className="w-12 h-12 animate-spin text-red-500" />
|
||||
<Loader2 className="w-12 h-12 animate-spin text-red-500 dark:text-red-400" />
|
||||
) : (
|
||||
<div className="w-12 h-12 rounded-xl bg-red-50 flex items-center justify-center group-hover:bg-red-100 transition-colors">
|
||||
<div className="w-12 h-12 rounded-xl bg-red-50 dark:bg-red-900/30 flex items-center justify-center group-hover:bg-red-100 dark:group-hover:bg-red-900/50 transition-colors">
|
||||
<svg viewBox="0 0 24 24" className="w-7 h-7">
|
||||
<path fill="#EA4335" d="M5.26 9.71L12 14.04l6.74-4.33-6.74-4.33z"/>
|
||||
<path fill="#34A853" d="M12 14.04l6.74-4.33v7.65c0 .7-.57 1.26-1.26 1.26H6.52c-.7 0-1.26-.57-1.26-1.26V9.71l6.74 4.33z"/>
|
||||
@@ -442,37 +442,37 @@ export function Setup() {
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1">
|
||||
<p className="font-semibold text-slate-900">Gmail</p>
|
||||
<p className="text-sm text-slate-500">Google Workspace</p>
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100">Gmail</p>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">Google Workspace</p>
|
||||
</div>
|
||||
<ChevronRight className="w-5 h-5 text-slate-400 group-hover:text-red-500 group-hover:translate-x-1 transition-all" />
|
||||
<ChevronRight className="w-5 h-5 text-slate-400 dark:text-slate-500 group-hover:text-red-500 dark:group-hover:text-red-400 group-hover:translate-x-1 transition-all" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={handleConnectOutlook}
|
||||
disabled={connecting !== null}
|
||||
className="flex items-center gap-4 p-6 bg-white rounded-2xl border-2 border-slate-200 hover:border-blue-300 hover:shadow-xl hover:shadow-blue-500/10 transition-all text-left group disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="flex items-center gap-4 p-6 bg-white dark:bg-slate-800 rounded-2xl border-2 border-slate-200 dark:border-slate-700 hover:border-blue-300 dark:hover:border-blue-600 hover:shadow-xl hover:shadow-blue-500/10 transition-all text-left group disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{connecting === 'outlook' ? (
|
||||
<Loader2 className="w-12 h-12 animate-spin text-blue-500" />
|
||||
<Loader2 className="w-12 h-12 animate-spin text-blue-500 dark:text-blue-400" />
|
||||
) : (
|
||||
<div className="w-12 h-12 rounded-xl bg-blue-50 flex items-center justify-center group-hover:bg-blue-100 transition-colors">
|
||||
<div className="w-12 h-12 rounded-xl bg-blue-50 dark:bg-blue-900/30 flex items-center justify-center group-hover:bg-blue-100 dark:group-hover:bg-blue-900/50 transition-colors">
|
||||
<svg viewBox="0 0 24 24" className="w-7 h-7">
|
||||
<path fill="#0078D4" d="M11.5 3v8.5H3V3h8.5zm1 0H21v8.5h-8.5V3zM3 12.5h8.5V21H3v-8.5zm9.5 0H21V21h-8.5v-8.5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1">
|
||||
<p className="font-semibold text-slate-900">Outlook</p>
|
||||
<p className="text-sm text-slate-500">Microsoft 365</p>
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100">Outlook</p>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">Microsoft 365</p>
|
||||
</div>
|
||||
<ChevronRight className="w-5 h-5 text-slate-400 group-hover:text-blue-500 group-hover:translate-x-1 transition-all" />
|
||||
<ChevronRight className="w-5 h-5 text-slate-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400 group-hover:translate-x-1 transition-all" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 p-4 bg-slate-50 rounded-xl max-w-lg mx-auto">
|
||||
<p className="text-sm text-slate-500">
|
||||
<div className="mt-10 p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl max-w-lg mx-auto">
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">
|
||||
🔒 Your data is secure. We don't store email content and only have read access.
|
||||
</p>
|
||||
</div>
|
||||
@@ -485,16 +485,16 @@ export function Setup() {
|
||||
<div className="w-24 h-24 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-primary-100 to-primary-200 flex items-center justify-center shadow-xl shadow-primary-500/10">
|
||||
<Settings className="w-12 h-12 text-primary-600" />
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold text-slate-900 mb-3">Sorting Settings</h1>
|
||||
<p className="text-lg text-slate-600 max-w-md mx-auto">
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100 mb-3">Sorting Settings</h1>
|
||||
<p className="text-lg text-slate-600 dark:text-slate-400 max-w-md mx-auto">
|
||||
Customize how strictly the AI should sort your emails.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Card className="max-w-lg mx-auto shadow-xl border-0">
|
||||
<Card className="max-w-lg mx-auto shadow-xl border-0 dark:bg-slate-800 dark:border-slate-700">
|
||||
<CardContent className="p-8 space-y-8">
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-slate-900 mb-4">Sorting Intensity</label>
|
||||
<label className="block text-sm font-semibold text-slate-900 dark:text-slate-100 mb-4">Sorting Intensity</label>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{[
|
||||
{ id: 'light', name: 'Light', desc: 'Only obvious distractions', emoji: '🌱' },
|
||||
@@ -506,30 +506,30 @@ export function Setup() {
|
||||
onClick={() => setPreferences(p => ({ ...p, sortingStrictness: option.id }))}
|
||||
className={`p-4 rounded-xl border-2 text-center transition-all ${
|
||||
preferences.sortingStrictness === option.id
|
||||
? 'border-primary-500 bg-primary-50 shadow-lg shadow-primary-500/10'
|
||||
: 'border-slate-200 hover:border-slate-300 bg-white'
|
||||
? 'border-primary-500 dark:border-primary-400 bg-primary-50 dark:bg-primary-900/30 shadow-lg shadow-primary-500/10'
|
||||
: 'border-slate-200 dark:border-slate-700 hover:border-slate-300 dark:hover:border-slate-600 bg-white dark:bg-slate-800'
|
||||
}`}
|
||||
>
|
||||
<span className="text-2xl mb-2 block">{option.emoji}</span>
|
||||
<p className="font-semibold text-slate-900">{option.name}</p>
|
||||
<p className="text-xs text-slate-500 mt-1">{option.desc}</p>
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100">{option.name}</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400 mt-1">{option.desc}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-5 bg-gradient-to-r from-slate-50 to-slate-100 rounded-xl">
|
||||
<div className="flex items-center justify-between p-5 bg-gradient-to-r from-slate-50 to-slate-100 dark:from-slate-800 dark:to-slate-700 rounded-xl">
|
||||
<div>
|
||||
<p className="font-semibold text-slate-900">Historical emails</p>
|
||||
<p className="text-sm text-slate-500">Analyze and sort last 30 days</p>
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100">Historical emails</p>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">Analyze and sort last 30 days</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setPreferences(p => ({ ...p, historicalSync: !p.historicalSync }))}
|
||||
className={`w-14 h-8 rounded-full transition-all duration-300 ${
|
||||
preferences.historicalSync ? 'bg-primary-500 shadow-lg shadow-primary-500/30' : 'bg-slate-300'
|
||||
preferences.historicalSync ? 'bg-primary-500 dark:bg-primary-600 shadow-lg shadow-primary-500/30' : 'bg-slate-300 dark:bg-slate-600'
|
||||
}`}
|
||||
>
|
||||
<div className={`w-6 h-6 bg-white rounded-full shadow-md transition-transform duration-300 ${
|
||||
<div className={`w-6 h-6 bg-white dark:bg-slate-200 rounded-full shadow-md transition-transform duration-300 ${
|
||||
preferences.historicalSync ? 'translate-x-7' : 'translate-x-1'
|
||||
}`} />
|
||||
</button>
|
||||
@@ -545,8 +545,8 @@ export function Setup() {
|
||||
<div className="w-24 h-24 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-primary-100 to-primary-200 flex items-center justify-center shadow-xl shadow-primary-500/10">
|
||||
<Zap className="w-12 h-12 text-primary-600" />
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold text-slate-900 mb-3">Choose your categories</h1>
|
||||
<p className="text-lg text-slate-600 max-w-md mx-auto">
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100 mb-3">Choose your categories</h1>
|
||||
<p className="text-lg text-slate-600 dark:text-slate-400 max-w-md mx-auto">
|
||||
Which categories should your emails be sorted into?
|
||||
</p>
|
||||
</div>
|
||||
@@ -558,21 +558,21 @@ export function Setup() {
|
||||
onClick={() => toggleCategory(category.id)}
|
||||
className={`flex items-center gap-4 p-5 rounded-xl border-2 text-left transition-all ${
|
||||
selectedCategories.includes(category.id)
|
||||
? 'border-primary-500 bg-primary-50 shadow-lg shadow-primary-500/10'
|
||||
: 'border-slate-200 bg-white hover:border-slate-300 hover:shadow-md'
|
||||
? 'border-primary-500 dark:border-primary-400 bg-primary-50 dark:bg-primary-900/30 shadow-lg shadow-primary-500/10'
|
||||
: 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 hover:border-slate-300 dark:hover:border-slate-600 hover:shadow-md'
|
||||
}`}
|
||||
>
|
||||
<div className={`w-12 h-12 rounded-xl ${category.color} flex items-center justify-center text-2xl shadow-lg`}>
|
||||
{category.icon}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-semibold text-slate-900">{category.name}</p>
|
||||
<p className="text-sm text-slate-500">{category.description}</p>
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100">{category.name}</p>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400">{category.description}</p>
|
||||
</div>
|
||||
<div className={`w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all ${
|
||||
selectedCategories.includes(category.id)
|
||||
? 'border-primary-500 bg-primary-500'
|
||||
: 'border-slate-300'
|
||||
? 'border-primary-500 dark:border-primary-400 bg-primary-500 dark:bg-primary-600'
|
||||
: 'border-slate-300 dark:border-slate-600'
|
||||
}`}>
|
||||
{selectedCategories.includes(category.id) && <Check className="w-4 h-4 text-white" />}
|
||||
</div>
|
||||
@@ -580,7 +580,7 @@ export function Setup() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-center text-sm text-slate-500 mt-6">
|
||||
<p className="text-center text-sm text-slate-500 dark:text-slate-400 mt-6">
|
||||
You can change these categories later in settings.
|
||||
</p>
|
||||
</div>
|
||||
@@ -591,20 +591,20 @@ export function Setup() {
|
||||
<div className="w-28 h-28 mx-auto mb-8 rounded-full bg-gradient-to-br from-green-100 to-green-200 flex items-center justify-center shadow-2xl shadow-green-500/20 animate-pulse">
|
||||
<Sparkles className="w-14 h-14 text-green-600" />
|
||||
</div>
|
||||
<h1 className="text-4xl font-bold text-slate-900 mb-4">All set! 🎉</h1>
|
||||
<p className="text-xl text-slate-600 mb-10 max-w-md mx-auto">
|
||||
<h1 className="text-4xl font-bold text-slate-900 dark:text-slate-100 mb-4">All set! 🎉</h1>
|
||||
<p className="text-xl text-slate-600 dark:text-slate-400 mb-10 max-w-md mx-auto">
|
||||
Your email account is connected. The AI will now start intelligent sorting.
|
||||
</p>
|
||||
|
||||
<div className="inline-flex items-center gap-4 p-5 bg-gradient-to-r from-slate-50 to-slate-100 rounded-2xl mb-10 shadow-lg">
|
||||
<div className="w-14 h-14 rounded-xl bg-white flex items-center justify-center shadow-md">
|
||||
<Mail className="w-7 h-7 text-primary-500" />
|
||||
<div className="inline-flex items-center gap-4 p-5 bg-gradient-to-r from-slate-50 to-slate-100 dark:from-slate-800 dark:to-slate-700 rounded-2xl mb-10 shadow-lg">
|
||||
<div className="w-14 h-14 rounded-xl bg-white dark:bg-slate-700 flex items-center justify-center shadow-md">
|
||||
<Mail className="w-7 h-7 text-primary-500 dark:text-primary-400" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p className="font-semibold text-slate-900 text-lg">
|
||||
<p className="font-semibold text-slate-900 dark:text-slate-100 text-lg">
|
||||
{connectedProvider === 'gmail' ? 'Gmail' : connectedProvider === 'outlook' ? 'Outlook' : 'Email'} connected
|
||||
</p>
|
||||
<p className="text-slate-500">{connectedEmail || user?.email}</p>
|
||||
<p className="text-slate-500 dark:text-slate-400">{connectedEmail || user?.email}</p>
|
||||
</div>
|
||||
<Badge variant="success" className="text-sm px-3 py-1">Active</Badge>
|
||||
</div>
|
||||
@@ -628,7 +628,7 @@ export function Setup() {
|
||||
|
||||
{currentStep !== 'connect' && currentStep !== 'complete' && (
|
||||
<div className="flex justify-between max-w-lg mx-auto">
|
||||
<Button variant="ghost" onClick={handleBack} className="text-slate-600">
|
||||
<Button variant="ghost" onClick={handleBack} className="text-slate-600 dark:text-slate-400">
|
||||
<ArrowLeft className="w-5 h-5 mr-2" />
|
||||
Back
|
||||
</Button>
|
||||
|
||||
@@ -51,26 +51,26 @@ export function VerifyEmail() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center p-4">
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center p-4">
|
||||
<div className="w-full max-w-md">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="flex items-center justify-center gap-2 mb-8">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-700 flex items-center justify-center">
|
||||
<Mail className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-xl font-bold text-slate-900">
|
||||
Email<span className="text-primary-600">Sorter</span>
|
||||
<span className="text-xl font-bold text-slate-900 dark:text-slate-100">
|
||||
Email<span className="text-primary-600 dark:text-primary-400">Sorter</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<Card className="shadow-xl border-0">
|
||||
<Card className="shadow-xl border-0 dark:bg-slate-800 dark:border-slate-700">
|
||||
<CardHeader className="text-center pb-2">
|
||||
<CardTitle className="text-2xl">
|
||||
<CardTitle className="text-2xl dark:text-slate-100">
|
||||
{status === 'loading' && 'E-Mail wird verifiziert...'}
|
||||
{status === 'success' && 'E-Mail verifiziert!'}
|
||||
{status === 'error' && 'Verifizierung fehlgeschlagen'}
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<CardDescription className="dark:text-slate-400">
|
||||
{status === 'loading' && 'Bitte warte einen Moment.'}
|
||||
{status === 'success' && 'Deine E-Mail-Adresse wurde erfolgreich bestätigt.'}
|
||||
{status === 'error' && error}
|
||||
@@ -79,25 +79,25 @@ export function VerifyEmail() {
|
||||
<CardContent>
|
||||
{status === 'loading' && (
|
||||
<div className="flex flex-col items-center py-12">
|
||||
<Loader2 className="w-12 h-12 animate-spin text-primary-500 mb-4" />
|
||||
<p className="text-slate-500">Verifizierung läuft...</p>
|
||||
<Loader2 className="w-12 h-12 animate-spin text-primary-500 dark:text-primary-400 mb-4" />
|
||||
<p className="text-slate-500 dark:text-slate-400">Verifizierung läuft...</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'success' && (
|
||||
<div className="text-center py-8">
|
||||
<div className="w-20 h-20 mx-auto mb-6 rounded-full bg-green-100 flex items-center justify-center">
|
||||
<CheckCircle className="w-10 h-10 text-green-600" />
|
||||
<div className="w-20 h-20 mx-auto mb-6 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
|
||||
<CheckCircle className="w-10 h-10 text-green-600 dark:text-green-400" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="p-4 bg-green-50 border border-green-100 rounded-xl">
|
||||
<p className="text-green-700 font-medium">
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/30 border border-green-100 dark:border-green-800 rounded-xl">
|
||||
<p className="text-green-700 dark:text-green-300 font-medium">
|
||||
Dein Account ist jetzt vollständig aktiviert!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-slate-600">
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Du kannst jetzt alle Features von EmailSorter nutzen.
|
||||
</p>
|
||||
|
||||
@@ -110,18 +110,18 @@ export function VerifyEmail() {
|
||||
|
||||
{status === 'error' && (
|
||||
<div className="text-center py-8">
|
||||
<div className="w-20 h-20 mx-auto mb-6 rounded-full bg-red-100 flex items-center justify-center">
|
||||
<XCircle className="w-10 h-10 text-red-600" />
|
||||
<div className="w-20 h-20 mx-auto mb-6 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">
|
||||
<XCircle className="w-10 h-10 text-red-600 dark:text-red-400" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="p-4 bg-red-50 border border-red-100 rounded-xl">
|
||||
<p className="text-red-700">
|
||||
<div className="p-4 bg-red-50 dark:bg-red-900/30 border border-red-100 dark:border-red-800 rounded-xl">
|
||||
<p className="text-red-700 dark:text-red-300">
|
||||
{error || 'Der Verifizierungslink ist ungültig oder abgelaufen.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-slate-600 text-sm">
|
||||
<p className="text-slate-600 dark:text-slate-400 text-sm">
|
||||
Falls dein Link abgelaufen ist, kannst du eine neue Verifizierungs-E-Mail anfordern.
|
||||
</p>
|
||||
|
||||
@@ -142,9 +142,9 @@ export function VerifyEmail() {
|
||||
</Card>
|
||||
|
||||
{/* Help text */}
|
||||
<p className="text-center text-sm text-slate-500 mt-6">
|
||||
<p className="text-center text-sm text-slate-500 dark:text-slate-400 mt-6">
|
||||
Probleme? Kontaktiere uns unter{' '}
|
||||
<a href="mailto:support@emailsorter.de" className="text-primary-600 hover:underline">
|
||||
<a href="mailto:support@emailsorter.de" className="text-primary-600 dark:text-primary-400 hover:underline">
|
||||
support@emailsorter.de
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user