import React, { useState, useEffect } from 'react';
import { Calendar, XCircle, ChevronLeft, ChevronRight, LogOut, User, Github, Mail } from 'lucide-react';
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Alert, AlertDescription } from '@/components/ui/alert';
const SocialLoginButton = ({ provider, icon: Icon, onClick, className }) => (
);
const AuthForm = ({ onLogin, onRegister, onSocialLogin }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLogin, setIsLogin] = useState(true);
const [error, setError] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
setError('');
try {
if (isLogin) {
await onLogin(email, password);
} else {
await onRegister(email, password);
}
} catch (err) {
setError(err.message);
}
};
return (
{isLogin ? 'Login' : 'Register'}
(
)}
onClick={() => onSocialLogin('google')}
className="bg-white hover:bg-gray-50"
/>
onSocialLogin('github')}
className="bg-[#24292F] hover:bg-[#24292F]/90 text-white"
/>
);
};
const HabitTracker = () => {
const [user, setUser] = useState(null);
const [habits, setHabits] = useState([]);
const [trackedData, setTrackedData] = useState({});
const [selectedDate, setSelectedDate] = useState(new Date());
const [newHabitName, setNewHabitName] = useState('');
const [newHabitColor, setNewHabitColor] = useState('#000000');
const [newHabitGoal, setNewHabitGoal] = useState('');
const [loading, setLoading] = useState(true);
useEffect(() => {
checkAuth();
}, []);
const checkAuth = async () => {
try {
const response = await fetch('/api/auth/check', {
credentials: 'include'
});
if (response.ok) {
const userData = await response.json();
setUser(userData);
}
} catch (error) {
console.error('Auth check failed:', error);
}
setLoading(false);
};
const handleLogin = async (email, password) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password })
});
if (!response.ok) {
throw new Error('Login failed');
}
const userData = await response.json();
setUser(userData);
};
const handleRegister = async (email, password) => {
const response = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password })
});
if (!response.ok) {
throw new Error('Registration failed');
}
const userData = await response.json();
setUser(userData);
};
const handleSocialLogin = async (provider) => {
try {
const response = await fetch(`/api/auth/${provider}`, {
method: 'POST',
credentials: 'include'
});
if (!response.ok) {
throw new Error(`${provider} login failed`);
}
const userData = await response.json();
setUser(userData);
} catch (error) {
throw new Error(`${provider} login failed: ${error.message}`);
}
};
const handleLogout = async () => {
try {
await fetch('/api/auth/logout', {
method: 'POST',
credentials: 'include'
});
setUser(null);
setHabits([]);
setTrackedData({});
} catch (error) {
console.error('Logout failed:', error);
}
};
if (loading) {
return (
);
}
if (!user) {
return (
);
}
return (
{user.email}
Habit Tracker
Or continue with email
{selectedDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
setNewHabitName(e.target.value)}
/>
setNewHabitColor(e.target.value)}
className="w-20"
/>
setNewHabitGoal(e.target.value)}
className="w-32"
/>
{habits.map(habit => (
{habit.name}
setHabits(habits.filter(h => h.id !== habit.id))}
/>
))}
{['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
);
};
export default HabitTracker;
{day}
))}
{Array.from({ length: 35 }, (_, i) => {
const date = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), i - selectedDate.getDay() + 1);
return (
{date.getDate()}
{habits.map(habit => (
);
})}
{
const dateStr = date.toISOString().split('T')[0];
const newTrackedData = { ...trackedData };
if (!newTrackedData[dateStr]) {
newTrackedData[dateStr] = [];
}
const index = newTrackedData[dateStr].indexOf(habit.id);
if (index === -1) {
newTrackedData[dateStr].push(habit.id);
} else {
newTrackedData[dateStr].splice(index, 1);
}
setTrackedData(newTrackedData);
}}
/>
))}