'use client';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { User } from '@/lib/session';
import { fetchPreferences, fetchReminderSettings, saveReminderSettings, ReminderSettings, UserPreferences } from '@/lib/storage';
import { useNotifications } from '@/hooks/useNotifications';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Cigarette, Leaf, LogOut, Home, ChevronDown, Sun, Moon, Bell, BellOff, BellRing, Menu, Sparkles, Link as LinkIcon } from 'lucide-react';
import { useTheme } from '@/lib/theme-context';
import { InstallAppButton } from './InstallAppButton';
import { cn } from '@/lib/utils';
import { SideMenu } from './SideMenu';
interface UserHeaderProps {
user: User;
preferences?: UserPreferences | null;
}
interface HourlyTimePickerProps {
value: string;
onChange: (time: string) => void;
}
function HourlyTimePicker({ value, onChange }: HourlyTimePickerProps) {
const [parsedHours, parsedMinutes] = value.split(':').map(Number);
const currentAmpm = parsedHours >= 12 ? 'PM' : 'AM';
const currentHour12 = parsedHours % 12 || 12;
const hourString = currentHour12.toString().padStart(2, '0');
const minuteString = parsedMinutes.toString().padStart(2, '0');
const updateTime = (newHourStr: string, newMinuteStr: string, newAmpmStr: string) => {
let h = parseInt(newHourStr);
if (newAmpmStr === 'PM' && h !== 12) h += 12;
if (newAmpmStr === 'AM' && h === 12) h = 0;
onChange(`${h.toString().padStart(2, '0')}:${newMinuteStr}`);
};
const hoursOptions = Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, '0'));
const minutesOptions = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'));
return (
{/* Hour Select */}
{/* Minute Select */}
{/* AM/PM Select */}
);
}
export function UserHeader({ user, preferences }: UserHeaderProps) {
const [userName, setUserName] = useState(null);
const [reminderSettings, setReminderSettings] = useState({ enabled: false, reminderTime: '09:00', frequency: 'daily' });
const [showReminderDialog, setShowReminderDialog] = useState(false);
const [isSideMenuOpen, setIsSideMenuOpen] = useState(false);
const [localTime, setLocalTime] = useState('09:00');
const [localFrequency, setLocalFrequency] = useState<'daily' | 'hourly'>('daily');
const router = useRouter();
const { theme, toggleTheme } = useTheme();
const { isSupported, permission, requestPermission } = useNotifications(reminderSettings);
// Helper to parse time string
const [parsedHours, parsedMinutes] = reminderSettings.reminderTime.split(':').map(Number);
const currentAmpm = parsedHours >= 12 ? 'PM' : 'AM';
const currentHour12 = parsedHours % 12 || 12;
const hourString = currentHour12.toString().padStart(2, '0');
const minuteString = parsedMinutes.toString().padStart(2, '0');
const updateTime = async (newHourStr: string, newMinuteStr: string, newAmpmStr: string) => {
let h = parseInt(newHourStr);
if (newAmpmStr === 'PM' && h !== 12) h += 12;
if (newAmpmStr === 'AM' && h === 12) h = 0;
const timeString = `${h.toString().padStart(2, '0')}:${newMinuteStr}`;
setLocalTime(timeString);
const newSettings = { ...reminderSettings, reminderTime: timeString };
setReminderSettings(newSettings);
await saveReminderSettings(newSettings);
};
// Generate options
const hoursOptions = Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, '0'));
const minutesOptions = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'));
useEffect(() => {
const loadData = async () => {
const [prefs, reminders] = await Promise.all([
preferences ? Promise.resolve(preferences) : fetchPreferences(),
fetchReminderSettings(),
]);
if (prefs) {
setUserName(prefs.userName);
}
const detectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
let settingsToUse = reminders;
if (reminders.timezone !== detectedTimezone) {
settingsToUse = { ...reminders, timezone: detectedTimezone };
await saveReminderSettings(settingsToUse);
}
setReminderSettings(settingsToUse);
setLocalTime(settingsToUse.reminderTime);
setLocalFrequency(settingsToUse.frequency || 'daily');
};
loadData();
}, [preferences]);
const handleToggleReminders = async () => {
if (!reminderSettings.enabled) {
const result = await requestPermission();
if (result !== 'granted') return;
}
const newSettings = { ...reminderSettings, enabled: !reminderSettings.enabled };
setReminderSettings(newSettings);
await saveReminderSettings(newSettings);
};
const handleFrequencyChange = async (newFrequency: 'daily' | 'hourly') => {
setLocalFrequency(newFrequency);
const newSettings = { ...reminderSettings, frequency: newFrequency };
setReminderSettings(newSettings);
await saveReminderSettings(newSettings);
};
const initials = [user.firstName?.[0], user.lastName?.[0]]
.filter(Boolean)
.join('')
.toUpperCase() || user.email[0].toUpperCase();
const handleNavigate = (path: string) => {
router.push(path);
setIsSideMenuOpen(false);
};
return (
<>
{/* Cloudy/Foggy effect overlay - removed mix-blend-overlay for visibility */}
{/* LEFT: User Profile / Side Menu Trigger */}
{/* CENTER: Title and Welcome Message */}
handleNavigate('/')}
style={{
background: theme === 'light'
? 'linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%)'
: 'linear-gradient(135deg, #a78bfa 0%, #f472b6 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text',
filter: theme === 'dark' ? 'drop-shadow(0 0 10px rgba(167, 139, 250, 0.3))' : 'none'
}}
>
QuitTraq
{userName && (
Welcome {userName}, you got this!
)}
{/* RIGHT: Action Buttons */}
{/* Side Menu Integration */}
setIsSideMenuOpen(false)}
user={user}
userName={userName}
/>
{/* Reminder Settings Dialog */}
>
);
}