feat: Hide tutorial on login, add 'Angemeldet bleiben' checkbox

- OnboardingTutorial: Skip on /login, /auth, /register paths
- AuthForm: Added remember-me checkbox (default: checked)
- Session persistence based on checkbox selection
This commit is contained in:
2025-12-26 22:46:22 +01:00
parent 1017ec2c57
commit 73a057b1e3
3 changed files with 56 additions and 7 deletions

View File

@@ -9,6 +9,7 @@ export default function AuthForm() {
const [isLogin, setIsLogin] = useState(true);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [rememberMe, setRememberMe] = useState(true);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [message, setMessage] = useState<string | null>(null);
@@ -21,8 +22,20 @@ export default function AuthForm() {
try {
if (isLogin) {
const { error } = await supabase.auth.signInWithPassword({ email, password });
// Set session persistence based on remember-me
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) throw error;
// If remember-me is checked, session will persist (default Supabase behavior)
// If not checked, clear session on browser close via localStorage flag
if (!rememberMe) {
sessionStorage.setItem('dramlog_session_only', 'true');
} else {
sessionStorage.removeItem('dramlog_session_only');
}
} else {
const { error } = await supabase.auth.signUp({
email,
@@ -88,6 +101,35 @@ export default function AuthForm() {
</div>
</div>
{/* Remember Me Checkbox - only show for login */}
{isLogin && (
<label className="flex items-center gap-3 cursor-pointer group">
<div className="relative">
<input
type="checkbox"
checked={rememberMe}
onChange={(e) => setRememberMe(e.target.checked)}
className="sr-only peer"
/>
<div className="w-5 h-5 bg-zinc-950 border border-zinc-700 rounded-md peer-checked:bg-orange-600 peer-checked:border-orange-600 transition-all" />
<svg
className="absolute inset-0 w-5 h-5 text-white opacity-0 peer-checked:opacity-100 transition-opacity"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
</div>
<span className="text-sm text-zinc-400 group-hover:text-zinc-300 transition-colors">
Angemeldet bleiben
</span>
</label>
)}
{error && (
<div className="flex items-center gap-2 p-3 bg-red-900/10 text-red-500 text-xs rounded-lg border border-red-900/20">
<AlertCircle size={16} />

View File

@@ -1,6 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import { usePathname } from 'next/navigation';
import { motion, AnimatePresence } from 'framer-motion';
import { Scan, GlassWater, Users, Settings, ArrowRight, X, Sparkles } from 'lucide-react';
@@ -49,8 +50,14 @@ const STEPS: OnboardingStep[] = [
export default function OnboardingTutorial() {
const [isOpen, setIsOpen] = useState(false);
const [currentStep, setCurrentStep] = useState(0);
const pathname = usePathname();
useEffect(() => {
// Don't show on login/auth pages
if (pathname === '/login' || pathname === '/auth' || pathname === '/register') {
return;
}
// Check if onboarding was completed
const completed = localStorage.getItem(ONBOARDING_KEY);
if (!completed) {
@@ -58,7 +65,7 @@ export default function OnboardingTutorial() {
const timer = setTimeout(() => setIsOpen(true), 1000);
return () => clearTimeout(timer);
}
}, []);
}, [pathname]);
const handleNext = () => {
if (currentStep < STEPS.length - 1) {
@@ -125,10 +132,10 @@ export default function OnboardingTutorial() {
<div
key={index}
className={`w-2 h-2 rounded-full transition-all ${index === currentStep
? 'w-6 bg-orange-500'
: index < currentStep
? 'bg-orange-500/50'
: 'bg-zinc-700'
? 'w-6 bg-orange-500'
: index < currentStep
? 'bg-orange-500/50'
: 'bg-zinc-700'
}`}
/>
))}

File diff suppressed because one or more lines are too long