Update onboarding steps and connection logic in ConnectStep component

- Changed the initial step in Onboarding from 4 to 1 to reflect the correct starting point.
- Enhanced ConnectStep by adding session management and connection checks for Telegram.
- Introduced a helper function to determine if a saved session exists in localStorage.
- Updated the connection options to disable buttons for already connected accounts and added visual feedback for connected status.

These changes improve the onboarding experience and ensure better handling of account connections.
This commit is contained in:
Steven Enamakel
2026-01-28 07:41:48 +05:30
parent d0e1191c88
commit bd1d240738
2 changed files with 93 additions and 35 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ import GetStartedStep from './steps/GetStartedStep';
const Onboarding = () => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const [currentStep, setCurrentStep] = useState(4);
const [currentStep, setCurrentStep] = useState(1);
const totalSteps = 5;
// Lottie animation files for each step
+92 -34
View File
@@ -1,4 +1,6 @@
import { useState } from 'react';
import { useState, useMemo } from 'react';
import { useAppSelector } from '../../../store/hooks';
import { selectIsAuthenticated } from '../../../store/telegramSelectors';
import GoogleIcon from '../../../assets/icons/GoogleIcon';
import TelegramConnectionModal from '../../../components/TelegramConnectionModal';
@@ -20,10 +22,43 @@ interface ConnectOption {
comingSoon?: boolean;
}
// Helper to check if there's a saved session in localStorage
const hasSavedSession = (): boolean => {
try {
return !!localStorage.getItem('telegram_session');
} catch {
return false;
}
};
const ConnectStep = ({ onNext }: ConnectStepProps) => {
const [isTelegramModalOpen, setIsTelegramModalOpen] = useState(false);
const isTelegramAuthenticated = useAppSelector(selectIsAuthenticated);
const sessionString = useAppSelector((state) => state.telegram.sessionString);
// Check if Telegram account is connected (authenticated or has saved session)
const isTelegramConnected = useMemo(() => {
return isTelegramAuthenticated || !!sessionString || hasSavedSession();
}, [isTelegramAuthenticated, sessionString]);
// Check if an account is connected
const isAccountConnected = (accountId: string): boolean => {
if (accountId === 'telegram') {
return isTelegramConnected;
}
// Add other account checks here when implemented
return false;
};
// Check if at least one account is connected
const hasConnectedAccount = isTelegramConnected; // Add other accounts when implemented
const handleConnect = (provider: string) => {
// Don't connect if already connected
if (isAccountConnected(provider)) {
return;
}
// In a real app, this would handle OAuth
console.log(`Connecting to ${provider}`);
@@ -44,23 +79,25 @@ const ConnectStep = ({ onNext }: ConnectStepProps) => {
};
const connectOptions: ConnectOption[] = [
{
id: 'telegram',
name: 'Telegram',
description: 'Organize chats, automate messages and get insights.',
icon: <img src={TelegramIcon} alt="Telegram" className="w-5 h-5" />,
},
{
id: 'google',
name: 'Google',
description: 'Manage emails, contacts and calendar events',
icon: <GoogleIcon />,
comingSoon: true,
},
{
id: 'notion',
name: 'Notion',
description: 'Manage tasks, documents and everything else in your Notion',
icon: <img src={NotionIcon} alt="Notion" className="w-5 h-5" />,
},
{
id: 'telegram',
name: 'Telegram',
description: 'Organize chats, automate messages and get insights.',
icon: <img src={TelegramIcon} alt="Telegram" className="w-5 h-5" />,
comingSoon: true,
},
{
id: 'wallet',
@@ -88,38 +125,59 @@ const ConnectStep = ({ onNext }: ConnectStepProps) => {
</div>
<div className="space-y-3 mb-4">
{connectOptions.map((option) => (
<button
key={option.id}
onClick={() => handleConnect(option.id)}
disabled={option.comingSoon}
className={`w-full flex items-start 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 text-left ${option.comingSoon ? 'opacity-50 cursor-not-allowed' : ''
}`}
>
<div className="flex-shrink-0 mt-0.5">{option.icon}</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between">
<span className="font-medium text-sm">{option.name}</span>
{option.comingSoon && (
<span className="text-xs opacity-60 bg-stone-700 px-2 py-0.5 rounded">Coming Soon</span>
)}
{connectOptions.map((option) => {
const isConnected = isAccountConnected(option.id);
const isDisabled = option.comingSoon || isConnected;
return (
<button
key={option.id}
onClick={() => handleConnect(option.id)}
disabled={isDisabled}
className={`w-full flex items-start space-x-3 p-3 bg-black/50 border border-stone-700 rounded-xl transition-all duration-200 text-left ${isDisabled
? 'opacity-50 cursor-not-allowed'
: 'hover:border-stone-600 hover:shadow-medium'
}`}
>
<div className="flex-shrink-0 mt-0.5">{option.icon}</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between">
<span className="font-medium text-sm">{option.name}</span>
{option.comingSoon && (
<span className="text-xs opacity-60 bg-stone-700 px-2 py-0.5 rounded">Coming Soon</span>
)}
{isConnected && !option.comingSoon && (
<span className="text-xs opacity-60 bg-green-700 px-2 py-0.5 rounded">Connected</span>
)}
</div>
<p className="opacity-70 text-xs mt-1">{option.description}</p>
</div>
<p className="opacity-70 text-xs mt-1">{option.description}</p>
</div>
</button>
))}
</button>
);
})}
</div>
<div className="mt-4 p-4 bg-sage-500/10 rounded-xl border border-sage-500/30">
<div className="flex items-start space-x-2">
<div>
<p className="font-medium text-sm">🔒 Remember everything is private &amp; encrypted!</p>
<p className="opacity-70 text-xs mt-1">All data and credentials are stored
locally and follows a strict zero-data retention policy so you won't have to worry about anything
getting leaked.</p>
{!hasConnectedAccount && (
<div className="mt-4 p-4 bg-sage-500/10 rounded-xl border border-sage-500/30">
<div className="flex items-start space-x-2">
<div>
<p className="font-medium text-sm">🔒 Remember everything is private &amp; encrypted!</p>
<p className="opacity-70 text-xs mt-1">All data and credentials are stored
locally and follows a strict zero-data retention policy so you won't have to worry about anything
getting leaked.</p>
</div>
</div>
</div>
</div>
)}
{hasConnectedAccount && (
<button
onClick={onNext}
className="btn-primary w-full py-2.5 text-sm font-medium rounded-xl mt-4"
>
Continue
</button>
)}
<TelegramConnectionModal
isOpen={isTelegramModalOpen}