Refactor PrivacyFeatureCard and Step1Privacy for improved layout and styling

- Adjusted padding and text styles in PrivacyFeatureCard for better readability and alignment.
- Updated privacy feature titles with icons to enhance visual appeal and user engagement.
- Modified layout in Step1Privacy to improve spacing and overall design consistency.
- Streamlined button styles for a more cohesive user experience.

This update enhances the onboarding process by making privacy features more visually engaging and easier to read, aligning with the focus on user security and clarity.
This commit is contained in:
Steven Enamakel
2026-01-28 00:39:18 +05:30
parent 27dc4037c1
commit 1087ae51ec
13 changed files with 444 additions and 528 deletions
+2 -8
View File
@@ -1,10 +1,7 @@
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import Welcome from './pages/Welcome';
import Login from './pages/Login';
import Step1Privacy from './pages/onboarding/Step1Privacy';
import Step2Analytics from './pages/onboarding/Step2Analytics';
import Step3Connect from './pages/onboarding/Step3Connect';
import Step4GetStarted from './pages/onboarding/Step4GetStarted';
import Onboarding from './pages/onboarding/Onboarding';
import Home from './pages/Home';
function App() {
@@ -13,10 +10,7 @@ function App() {
<Routes>
<Route path="/" element={<Welcome />} />
<Route path="/login" element={<Login />} />
<Route path="/onboarding/step1" element={<Step1Privacy />} />
<Route path="/onboarding/step2" element={<Step2Analytics />} />
<Route path="/onboarding/step3" element={<Step3Connect />} />
<Route path="/onboarding/step4" element={<Step4GetStarted />} />
<Route path="/onboarding" element={<Onboarding />} />
<Route path="/home" element={<Home />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
+3 -3
View File
@@ -5,11 +5,11 @@ interface PrivacyFeatureCardProps {
const PrivacyFeatureCard = ({ title, description }: PrivacyFeatureCardProps) => {
return (
<div className="bg-stone-800/50 rounded-xl p-6 border border-stone-700">
<div className="bg-stone-800/50 rounded-xl p-3 border border-stone-700">
<div className="flex items-start space-x-4">
<div>
<h3 className="font-semibold mb-2">{title}</h3>
<p className="opacity-70 text-sm leading-relaxed">{description}</p>
<h3 className="font-semibold text-sm mb-2 text-center">{title}</h3>
<p className="opacity-70 text-xs leading-relaxed">{description}</p>
</div>
</div>
</div>
+21
View File
@@ -0,0 +1,21 @@
interface ProgressIndicatorProps {
currentStep: number;
totalSteps: number;
}
const ProgressIndicator = ({ currentStep, totalSteps }: ProgressIndicatorProps) => {
return (
<div className="flex items-center justify-center space-x-1.5 mb-6">
{Array.from({ length: totalSteps }).map((_, index) => (
<div
key={index}
className={`w-8 h-0.5 rounded-full ${
index < currentStep ? 'bg-primary-500' : 'bg-stone-700'
}`}
/>
))}
</div>
);
};
export default ProgressIndicator;
+1 -1
View File
@@ -17,7 +17,7 @@ const Welcome = () => {
];
const handleTelegramLogin = () => {
navigate('/onboarding/step1');
navigate('/onboarding');
};
return (
+65
View File
@@ -0,0 +1,65 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import ProgressIndicator from '../../components/ProgressIndicator';
import PrivacyStep from './steps/PrivacyStep';
import AnalyticsStep from './steps/AnalyticsStep';
import ConnectStep from './steps/ConnectStep';
import GetStartedStep from './steps/GetStartedStep';
const Onboarding = () => {
const navigate = useNavigate();
const [currentStep, setCurrentStep] = useState(1);
const totalSteps = 4;
const handleNext = () => {
if (currentStep < totalSteps) {
setCurrentStep(currentStep + 1);
}
};
const handleBack = () => {
if (currentStep > 1) {
setCurrentStep(currentStep - 1);
} else {
navigate('/');
}
};
const handleComplete = () => {
navigate('/home');
};
const renderStep = () => {
switch (currentStep) {
case 1:
return <PrivacyStep onNext={handleNext} />;
case 2:
return <AnalyticsStep onNext={handleNext} />;
case 3:
return <ConnectStep onNext={handleNext} />;
case 4:
return <GetStartedStep onComplete={handleComplete} />;
default:
return <PrivacyStep onNext={handleNext} />;
}
};
return (
<div className="min-h-screen relative flex items-center justify-center">
<div className="relative z-10 max-w-lg w-full mx-4">
<ProgressIndicator currentStep={currentStep} totalSteps={totalSteps} />
{renderStep()}
{currentStep > 1 && (
<button
onClick={handleBack}
className="mt-6 w-full opacity-60 hover:opacity-100 text-sm font-medium transition-opacity"
>
Back
</button>
)}
</div>
</div>
);
};
export default Onboarding;
-82
View File
@@ -1,82 +0,0 @@
import { useNavigate } from 'react-router-dom';
import PrivacyFeatureCard from '../../components/PrivacyFeatureCard';
const Step1Privacy = () => {
const navigate = useNavigate();
const handleContinue = () => {
navigate('/onboarding/step2');
};
const privacyFeatures = [
{
title: 'Client-Side Encryption',
description: 'Your data is encrypted in your browser before it ever reaches our servers. We store only ciphertext. Without your recovery phrase, your content is cryptographically unreadable AES-256-GCM. Keys never leave your device',
},
{
title: 'Zero Admin Access',
description: 'Even with full database access, Momo admins cannot decrypt your content. Your encryption keys exist only in your browser. We have no mechanism to access them.',
},
{
title: 'Zero Data Retention',
description: 'Your data is NEVER used to train AI models. We operate under a Zero Data Retention contract with Anthropic. Your queries are processed and immediately discarded, never stored or used for training.',
},
];
return (
<div className="min-h-screen relative flex items-center justify-center">
{/* Main content */}
<div className="relative z-10 max-w-md w-full mx-4">
{/* Progress indicator */}
<div className="flex items-center justify-center space-x-2 mb-8">
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">1</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">2</div>
<div className="w-12 h-1 bg-stone-700 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">3</div>
<div className="w-12 h-1 bg-stone-700 mx-2"></div>
</div>
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">4</div>
</div>
{/* Privacy card */}
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-8">
<h1 className="text-xl font-bold mb-2">
Privacy
</h1>
<p className="opacity-70 text-sm">
A quick overview of how your privacy is protected with AlphaHuman
</p>
</div>
{/* Privacy Features Section */}
<div className="space-y-4 mb-8">
{privacyFeatures.map((feature, index) => (
<PrivacyFeatureCard
key={index}
title={feature.title}
description={feature.description}
/>
))}
</div>
{/* Continue button */}
<button
onClick={handleContinue}
className="btn-primary w-full py-4 text-lg font-semibold rounded-xl"
>
Continue
</button>
</div>
</div>
</div>
);
};
export default Step1Privacy;
-147
View File
@@ -1,147 +0,0 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
const Step2Analytics = () => {
const navigate = useNavigate();
const [selectedOption, setSelectedOption] = useState('maximumPrivacy');
const handleContinue = () => {
navigate('/onboarding/step3');
};
return (
<div className="min-h-screen relative flex items-center justify-center">
{/* Main content */}
<div className="relative z-10 max-w-md w-full mx-4">
{/* Progress indicator */}
<div className="flex items-center justify-center space-x-2 mb-8">
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">1</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">2</div>
<div className="w-12 h-1 bg-stone-700 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">3</div>
<div className="w-12 h-1 bg-stone-700 mx-2"></div>
</div>
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">4</div>
</div>
{/* Analytics card */}
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-8">
<h1 className="text-2xl font-bold mb-2">
Analytics
</h1>
<p className="opacity-70">
Help us improve your experience while maintaining your privacy
</p>
</div>
{/* Analytics options */}
<div className="space-y-4 mb-8">
{/* Securely Share Analytics */}
<div
className={`p-4 rounded-xl border-2 cursor-pointer transition-all ${
selectedOption === 'shareAnalytics'
? 'border-primary-500 bg-primary-500/20'
: 'border-stone-700 bg-black/50 hover:border-stone-600'
}`}
onClick={() => setSelectedOption('shareAnalytics')}
>
<div className="flex items-start space-x-4">
<div className="flex items-center justify-center mt-0.5">
<div className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
selectedOption === 'shareAnalytics'
? 'border-primary-500 bg-primary-500'
: 'border-stone-600 bg-black'
}`}>
{selectedOption === 'shareAnalytics' && (
<div className="w-2 h-2 bg-white rounded-full"></div>
)}
</div>
</div>
<div>
<h3 className="font-semibold mb-1">Securely Share Analytics</h3>
<p className="opacity-70 text-sm leading-relaxed">
Share anonymized usage data to help us improve features and performance. All data is encrypted and cannot be traced back to you.
</p>
</div>
</div>
</div>
{/* Maximum Privacy */}
<div
className={`p-4 rounded-xl border-2 cursor-pointer transition-all ${
selectedOption === 'maximumPrivacy'
? 'border-primary-500 bg-primary-500/20'
: 'border-stone-700 bg-black/50 hover:border-stone-600'
}`}
onClick={() => setSelectedOption('maximumPrivacy')}
>
<div className="flex items-start space-x-4">
<div className="flex items-center justify-center mt-0.5">
<div className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
selectedOption === 'maximumPrivacy'
? 'border-primary-500 bg-primary-500'
: 'border-stone-600 bg-black'
}`}>
{selectedOption === 'maximumPrivacy' && (
<div className="w-2 h-2 bg-white rounded-full"></div>
)}
</div>
</div>
<div>
<h3 className="font-semibold mb-1">Maximum Privacy</h3>
<p className="opacity-70 text-sm leading-relaxed">
Keep all your data completely private. We won't collect any usage analytics, ensuring total anonymity.
</p>
<div className="flex items-center space-x-1 mt-2">
<svg className="w-4 h-4 text-primary-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 1L5 6v4c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V6l-5-5z"/>
</svg>
<span className="text-primary-400 text-xs font-medium">Recommended for privacy</span>
</div>
</div>
</div>
</div>
</div>
{/* Continue button */}
<button
onClick={handleContinue}
className="btn-primary w-full py-4 text-lg font-semibold rounded-xl"
>
Continue
</button>
{/* Privacy note */}
<div className="mt-6 p-4 bg-stone-800/50 rounded-xl border border-stone-700">
<div className="flex items-start space-x-2">
<svg className="w-5 h-5 text-sage-400 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd"/>
</svg>
<div>
<p className="font-medium text-sm">You can change this setting anytime</p>
<p className="opacity-70 text-xs mt-1">Your privacy preferences can be updated in your account settings</p>
</div>
</div>
</div>
</div>
{/* Back button */}
<button
onClick={() => navigate('/onboarding/step1')}
className="mt-6 w-full opacity-60 hover:opacity-100 text-sm font-medium transition-opacity"
>
Back
</button>
</div>
</div>
);
};
export default Step2Analytics;
-149
View File
@@ -1,149 +0,0 @@
import { useNavigate } from 'react-router-dom';
const Step3Connect = () => {
const navigate = useNavigate();
const handleGoogleConnect = () => {
// In a real app, this would handle Google OAuth
navigate('/onboarding/step4');
};
const handleMicrosoftConnect = () => {
// In a real app, this would handle Microsoft OAuth
navigate('/onboarding/step4');
};
const handleDiscordConnect = () => {
// In a real app, this would handle Discord OAuth
navigate('/onboarding/step4');
};
const handleTwitterConnect = () => {
// In a real app, this would handle Twitter/X OAuth
navigate('/onboarding/step4');
};
const handleSkip = () => {
navigate('/onboarding/step4');
};
return (
<div className="min-h-screen relative flex items-center justify-center">
{/* Main content */}
<div className="relative z-10 max-w-md w-full mx-4">
{/* Progress indicator */}
<div className="flex items-center justify-center space-x-2 mb-8">
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">1</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">2</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">3</div>
<div className="w-12 h-1 bg-stone-700 mx-2"></div>
</div>
<div className="w-8 h-8 bg-stone-700 rounded-full flex items-center justify-center text-white text-sm font-semibold">4</div>
</div>
{/* Connect Account card */}
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-8">
<h1 className="text-2xl font-bold mb-2">
Connect Accounts
</h1>
<p className="opacity-70">
Connect your accounts to personalize your experience
</p>
</div>
{/* Connection options */}
<div className="space-y-4 mb-8">
{/* Google */}
<button
onClick={handleGoogleConnect}
className="w-full flex items-center justify-center space-x-3 p-4 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200 group"
>
<svg className="w-6 h-6" viewBox="0 0 24 24">
<path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
<path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
<path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
</svg>
<span className="font-medium">Use Google</span>
</button>
{/* Microsoft */}
<button
onClick={handleMicrosoftConnect}
className="w-full flex items-center justify-center space-x-3 p-4 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200 group"
>
<svg className="w-6 h-6" viewBox="0 0 24 24">
<path fill="#f25022" d="M1 1h10v10H1z"/>
<path fill="#00a4ef" d="M13 1h10v10H13z"/>
<path fill="#7fba00" d="M1 13h10v10H1z"/>
<path fill="#ffb900" d="M13 13h10v10H13z"/>
</svg>
<span className="font-medium">Use Microsoft</span>
</button>
{/* Discord */}
<button
onClick={handleDiscordConnect}
className="w-full flex items-center justify-center space-x-3 p-4 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200 group"
>
<svg className="w-6 h-6" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
</svg>
<span className="font-medium">Use Discord</span>
</button>
{/* Twitter/X */}
<button
onClick={handleTwitterConnect}
className="w-full flex items-center justify-center space-x-3 p-4 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200 group"
>
<svg className="w-6 h-6" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
<span className="font-medium">Use Twitter/X</span>
</button>
</div>
{/* Skip option */}
<button
onClick={handleSkip}
className="w-full py-3 opacity-60 hover:opacity-100 font-medium transition-opacity"
>
Skip for now
</button>
{/* Privacy note */}
<div className="mt-6 p-4 bg-stone-800/50 rounded-xl border border-stone-700">
<div className="flex items-start space-x-2">
<svg className="w-5 h-5 text-primary-400 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 1L5 6v4c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V6l-5-5z"/>
</svg>
<div>
<p className="font-medium text-sm">Your data stays private</p>
<p className="opacity-70 text-xs mt-1">We only use connected accounts for account notifications and security</p>
</div>
</div>
</div>
</div>
{/* Back button */}
<button
onClick={() => navigate('/onboarding/step2')}
className="mt-6 w-full opacity-60 hover:opacity-100 text-sm font-medium transition-opacity"
>
Back
</button>
</div>
</div>
);
};
export default Step3Connect;
-138
View File
@@ -1,138 +0,0 @@
import { useNavigate } from 'react-router-dom';
import { openUrl } from '@tauri-apps/plugin-opener';
import { TELEGRAM_BOT_USERNAME } from '../../utils/config';
const Step4GetStarted = () => {
const navigate = useNavigate();
const handleOpenTelegram = async () => {
try {
await openUrl(`https://t.me/${TELEGRAM_BOT_USERNAME}`);
// Navigate to home after opening Telegram
setTimeout(() => {
navigate('/home');
}, 1000);
} catch (error) {
console.error('Failed to open Telegram:', error);
}
};
const handleSkip = () => {
navigate('/home');
};
return (
<div className="min-h-screen relative flex items-center justify-center">
{/* Main content */}
<div className="relative z-10 max-w-md w-full mx-4">
{/* Progress indicator */}
<div className="flex items-center justify-center space-x-2 mb-8">
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">1</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">2</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="flex items-center">
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">3</div>
<div className="w-12 h-1 bg-primary-500 mx-2"></div>
</div>
<div className="w-8 h-8 bg-primary-500 rounded-full flex items-center justify-center text-white text-sm font-semibold">4</div>
</div>
{/* Get Started card */}
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-8">
<div className="w-16 h-16 mx-auto mb-4 bg-blue-500 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-white" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>
</svg>
</div>
<h1 className="text-2xl font-bold mb-2">
Get Started
</h1>
<p className="opacity-70">
Start messaging the bot to begin your crypto journey
</p>
</div>
{/* Instructions */}
<div className="space-y-4 mb-8">
<div className="bg-stone-800/50 rounded-xl p-6 border border-stone-700">
<div className="flex items-start space-x-4">
<div className="w-10 h-10 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold">1</span>
</div>
<div>
<h3 className="font-semibold mb-1">Open Telegram</h3>
<p className="opacity-70 text-sm">
Click the button below to open the AlphaHuman bot in Telegram
</p>
</div>
</div>
</div>
<div className="bg-stone-800/50 rounded-xl p-6 border border-stone-700">
<div className="flex items-start space-x-4">
<div className="w-10 h-10 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold">2</span>
</div>
<div>
<h3 className="font-semibold mb-1">Start Messaging</h3>
<p className="opacity-70 text-sm">
Send a message to the bot to get started. Try asking about crypto prices, market trends, or anything crypto-related!
</p>
</div>
</div>
</div>
<div className="bg-stone-800/50 rounded-xl p-6 border border-stone-700">
<div className="flex items-start space-x-4">
<div className="w-10 h-10 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold">3</span>
</div>
<div>
<h3 className="font-semibold mb-1">Cook! 🔥</h3>
<p className="opacity-70 text-sm">
The bot will help you with research, analysis, and staying on top of the crypto market
</p>
</div>
</div>
</div>
</div>
{/* Open Telegram button */}
<button
onClick={handleOpenTelegram}
className="w-full flex items-center justify-center space-x-3 bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white font-semibold py-4 rounded-xl transition-all duration-300 hover:shadow-medium mb-4"
>
<svg className="w-6 h-6" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>
</svg>
<span>Open Telegram Bot</span>
</button>
{/* Skip option */}
<button
onClick={handleSkip}
className="w-full py-3 opacity-60 hover:opacity-100 font-medium transition-opacity"
>
Skip for now
</button>
</div>
{/* Back button */}
<button
onClick={() => navigate('/onboarding/step3')}
className="mt-6 w-full opacity-60 hover:opacity-100 text-sm font-medium transition-opacity"
>
Back
</button>
</div>
</div>
);
};
export default Step4GetStarted;
@@ -0,0 +1,111 @@
import { useState } from 'react';
interface AnalyticsStepProps {
onNext: () => void;
}
const AnalyticsStep = ({ onNext }: AnalyticsStepProps) => {
const [selectedOption, setSelectedOption] = useState('maximumPrivacy');
return (
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-4">
<h1 className="text-xl font-bold mb-2">Analytics</h1>
<p className="opacity-70 text-sm">
Help us improve your experience while maintaining your privacy
</p>
</div>
<div className="space-y-4 mb-4">
<div
className={`p-4 rounded-xl border-2 cursor-pointer transition-all ${
selectedOption === 'shareAnalytics'
? 'border-primary-500 bg-primary-500/20'
: 'border-stone-700 bg-black/50 hover:border-stone-600'
}`}
onClick={() => setSelectedOption('shareAnalytics')}
>
<div className="flex items-start space-x-4">
<div className="flex items-center justify-center mt-0.5">
<div
className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
selectedOption === 'shareAnalytics'
? 'border-primary-500 bg-primary-500'
: 'border-stone-600 bg-black'
}`}
>
{selectedOption === 'shareAnalytics' && (
<div className="w-2 h-2 bg-white rounded-full"></div>
)}
</div>
</div>
<div>
<h3 className="font-semibold mb-1 text-sm">Securely Share Analytics</h3>
<p className="opacity-70 text-xs leading-relaxed">
Share anonymized usage data to help us improve features and performance. All data is encrypted and cannot be traced back to you.
</p>
</div>
</div>
</div>
<div
className={`p-4 rounded-xl border-2 cursor-pointer transition-all ${
selectedOption === 'maximumPrivacy'
? 'border-primary-500 bg-primary-500/20'
: 'border-stone-700 bg-black/50 hover:border-stone-600'
}`}
onClick={() => setSelectedOption('maximumPrivacy')}
>
<div className="flex items-start space-x-4">
<div className="flex items-center justify-center mt-0.5">
<div
className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
selectedOption === 'maximumPrivacy'
? 'border-primary-500 bg-primary-500'
: 'border-stone-600 bg-black'
}`}
>
{selectedOption === 'maximumPrivacy' && (
<div className="w-2 h-2 bg-white rounded-full"></div>
)}
</div>
</div>
<div>
<h3 className="font-semibold mb-1 text-sm">Maximum Privacy</h3>
<p className="opacity-70 text-xs leading-relaxed">
Keep all your data completely private. We won't collect any usage analytics, ensuring total anonymity.
</p>
<div className="flex items-center space-x-1 mt-2">
<svg className="w-4 h-4 text-primary-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 1L5 6v4c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V6l-5-5z"/>
</svg>
<span className="text-primary-400 text-xs font-medium">Recommended for privacy</span>
</div>
</div>
</div>
</div>
</div>
<button
onClick={onNext}
className="btn-primary w-full py-2.5 text-sm font-medium rounded-xl mb-4"
>
Continue
</button>
<div className="p-4 bg-stone-800/50 rounded-xl border border-stone-700">
<div className="flex items-start space-x-2">
<svg className="w-5 h-5 text-sage-400 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd"/>
</svg>
<div>
<p className="font-medium text-sm">You can change this setting anytime</p>
<p className="opacity-70 text-xs mt-1">Your privacy preferences can be updated in your account settings</p>
</div>
</div>
</div>
</div>
);
};
export default AnalyticsStep;
@@ -0,0 +1,91 @@
interface ConnectStepProps {
onNext: () => void;
}
const ConnectStep = ({ onNext }: ConnectStepProps) => {
const handleConnect = (provider: string) => {
// In a real app, this would handle OAuth
console.log(`Connecting to ${provider}`);
onNext();
};
return (
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-4">
<h1 className="text-xl font-bold mb-2">Connect Accounts</h1>
<p className="opacity-70 text-sm">
Connect your accounts to personalize your experience
</p>
</div>
<div className="space-y-3 mb-4">
<button
onClick={() => handleConnect('google')}
className="w-full flex items-center justify-center space-x-3 p-3 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200"
>
<svg className="w-5 h-5" viewBox="0 0 24 24">
<path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
<path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
<path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
</svg>
<span className="font-medium text-sm">Use Google</span>
</button>
<button
onClick={() => handleConnect('microsoft')}
className="w-full flex items-center justify-center space-x-3 p-3 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200"
>
<svg className="w-5 h-5" viewBox="0 0 24 24">
<path fill="#f25022" d="M1 1h10v10H1z"/>
<path fill="#00a4ef" d="M13 1h10v10H13z"/>
<path fill="#7fba00" d="M1 13h10v10H1z"/>
<path fill="#ffb900" d="M13 13h10v10H13z"/>
</svg>
<span className="font-medium text-sm">Use Microsoft</span>
</button>
<button
onClick={() => handleConnect('discord')}
className="w-full flex items-center justify-center space-x-3 p-3 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200"
>
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
</svg>
<span className="font-medium text-sm">Use Discord</span>
</button>
<button
onClick={() => handleConnect('twitter')}
className="w-full flex items-center justify-center space-x-3 p-3 bg-black/50 border border-stone-700 rounded-xl hover:border-stone-600 hover:shadow-medium transition-all duration-200"
>
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
<span className="font-medium text-sm">Use Twitter/X</span>
</button>
</div>
<button
onClick={onNext}
className="w-full py-2.5 opacity-60 hover:opacity-100 font-medium text-sm transition-opacity"
>
Skip for now
</button>
<div className="mt-4 p-4 bg-stone-800/50 rounded-xl border border-stone-700">
<div className="flex items-start space-x-2">
<svg className="w-5 h-5 text-primary-400 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 1L5 6v4c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V6l-5-5z"/>
</svg>
<div>
<p className="font-medium text-sm">Your data stays private</p>
<p className="opacity-70 text-xs mt-1">We only use connected accounts for account notifications and security</p>
</div>
</div>
</div>
</div>
);
};
export default ConnectStep;
@@ -0,0 +1,98 @@
import { openUrl } from '@tauri-apps/plugin-opener';
import { TELEGRAM_BOT_USERNAME } from '../../../utils/config';
interface GetStartedStepProps {
onComplete: () => void;
}
const GetStartedStep = ({ onComplete }: GetStartedStepProps) => {
const handleOpenTelegram = async () => {
try {
await openUrl(`https://t.me/${TELEGRAM_BOT_USERNAME}`);
setTimeout(() => {
onComplete();
}, 1000);
} catch (error) {
console.error('Failed to open Telegram:', error);
}
};
return (
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-4">
<div className="w-16 h-16 mx-auto mb-4 bg-blue-500 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-white" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>
</svg>
</div>
<h1 className="text-xl font-bold mb-2">Get Started</h1>
<p className="opacity-70 text-sm">
Start messaging the bot to begin your crypto journey
</p>
</div>
<div className="space-y-3 mb-4">
<div className="bg-stone-800/50 rounded-xl p-4 border border-stone-700">
<div className="flex items-start space-x-3">
<div className="w-8 h-8 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold text-xs">1</span>
</div>
<div>
<h3 className="font-semibold mb-1 text-sm">Open Telegram</h3>
<p className="opacity-70 text-xs">
Click the button below to open the AlphaHuman bot in Telegram
</p>
</div>
</div>
</div>
<div className="bg-stone-800/50 rounded-xl p-4 border border-stone-700">
<div className="flex items-start space-x-3">
<div className="w-8 h-8 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold text-xs">2</span>
</div>
<div>
<h3 className="font-semibold mb-1 text-sm">Start Messaging</h3>
<p className="opacity-70 text-xs">
Send a message to the bot to get started. Try asking about crypto prices, market trends, or anything crypto-related!
</p>
</div>
</div>
</div>
<div className="bg-stone-800/50 rounded-xl p-4 border border-stone-700">
<div className="flex items-start space-x-3">
<div className="w-8 h-8 bg-primary-500 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-white font-bold text-xs">3</span>
</div>
<div>
<h3 className="font-semibold mb-1 text-sm">Cook! 🔥</h3>
<p className="opacity-70 text-xs">
The bot will help you with research, analysis, and staying on top of the crypto market
</p>
</div>
</div>
</div>
</div>
<button
onClick={handleOpenTelegram}
className="w-full flex items-center justify-center space-x-3 bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white font-semibold py-2.5 text-sm rounded-xl transition-all duration-300 hover:shadow-medium mb-3"
>
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>
</svg>
<span>Open Telegram Bot</span>
</button>
<button
onClick={onComplete}
className="w-full py-2.5 opacity-60 hover:opacity-100 font-medium text-sm transition-opacity"
>
Skip for now
</button>
</div>
);
};
export default GetStartedStep;
@@ -0,0 +1,52 @@
import PrivacyFeatureCard from '../../../components/PrivacyFeatureCard';
interface PrivacyStepProps {
onNext: () => void;
}
const PrivacyStep = ({ onNext }: PrivacyStepProps) => {
const privacyFeatures = [
{
title: '🔒 Client-Side Encryption',
description: 'Your data is encrypted in your browser before it ever reaches our servers. We store only ciphertext. Without your recovery phrase, your content is cryptographically unreadable AES-256-GCM. Keys never leave your device',
},
{
title: '🙈 Zero Admin Access',
description: 'Even with full database access, Momo admins cannot decrypt your content. Your encryption keys exist only in your browser. We have no mechanism to access them.',
},
{
title: '🚫 Zero Data Retention',
description: 'Your data is NEVER used to train AI models. We operate under a Zero Data Retention contract with Anthropic. Your queries are processed and immediately discarded, never stored or used for training.',
},
];
return (
<div className="glass rounded-3xl p-8 shadow-large animate-fade-up">
<div className="text-center mb-4">
<h1 className="text-xl font-bold mb-2">Privacy</h1>
<p className="opacity-70 text-sm">
A quick overview of how your privacy is protected with AlphaHuman
</p>
</div>
<div className="space-y-2 mb-4">
{privacyFeatures.map((feature, index) => (
<PrivacyFeatureCard
key={index}
title={feature.title}
description={feature.description}
/>
))}
</div>
<button
onClick={onNext}
className="btn-primary w-full py-2.5 text-sm font-medium rounded-xl"
>
Continue
</button>
</div>
);
};
export default PrivacyStep;