'use client' import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Textarea } from '@/components/ui/textarea' import { currentUserAtom, settingsAtom, usersAtom } from '@/lib/atoms' import { INITIAL_DUE, INITIAL_RECURRENCE_RULE, MAX_COIN_LIMIT, QUICK_DATES } from '@/lib/constants' import { Habit } from '@/lib/types' import { convertHumanReadableFrequencyToMachineReadable, convertMachineReadableFrequencyToHumanReadable, d2t, serializeRRule } from '@/lib/utils' import { useAtom } from 'jotai' import { Zap } from 'lucide-react' import { DateTime } from 'luxon' import { useTranslations } from 'next-intl' import { useState } from 'react' import { RRule } from 'rrule' import EmojiPickerButton from './EmojiPickerButton' import ModalOverlay from './ModalOverlay'; // Import the new component interface AddEditHabitModalProps { onClose: () => void onSave: (habit: Omit) => Promise habit?: Habit | null isTask: boolean } export default function AddEditHabitModal({ onClose, onSave, habit, isTask }: AddEditHabitModalProps) { const t = useTranslations('AddEditHabitModal'); const [settings] = useAtom(settingsAtom) const [name, setName] = useState(habit?.name || '') const [description, setDescription] = useState(habit?.description || '') const [coinReward, setCoinReward] = useState(habit?.coinReward || 1) const [targetCompletions, setTargetCompletions] = useState(habit?.targetCompletions || 1) const isRecurRule = !isTask // Initialize ruleText with the actual frequency string or default, not the display text const initialRuleText = habit?.frequency ? convertMachineReadableFrequencyToHumanReadable({ frequency: habit.frequency, isRecurRule, timezone: settings.system.timezone }) : (isRecurRule ? INITIAL_RECURRENCE_RULE : INITIAL_DUE); const [ruleText, setRuleText] = useState(initialRuleText) const [currentUser] = useAtom(currentUserAtom) const [isQuickDatesOpen, setIsQuickDatesOpen] = useState(false) const [selectedUserIds, setSelectedUserIds] = useState((habit?.userIds || []).filter(id => id !== currentUser?.id)) const [usersData] = useAtom(usersAtom) const users = usersData.users function getFrequencyUpdate() { if (ruleText === initialRuleText && habit?.frequency) { // If text hasn't changed and original frequency exists, return it return habit.frequency; } const parsedResult = convertHumanReadableFrequencyToMachineReadable({ text: ruleText, timezone: settings.system.timezone, isRecurring: isRecurRule }); if (parsedResult.result) { return isRecurRule ? serializeRRule(parsedResult.result as RRule) : d2t({ dateTime: parsedResult.result as DateTime, timezone: settings.system.timezone }); } else { return 'invalid'; } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() await onSave({ name, description, coinReward, targetCompletions: targetCompletions > 1 ? targetCompletions : undefined, completions: habit?.completions || [], frequency: getFrequencyUpdate(), userIds: selectedUserIds.length > 0 ? selectedUserIds.concat(currentUser?.id || []) : (currentUser && [currentUser.id]) }) } const { result, message: errorMessage } = convertHumanReadableFrequencyToMachineReadable({ text: ruleText, timezone: settings.system.timezone, isRecurring: isRecurRule }); return ( <> {/* DialogContent from shadcn/ui is typically z-50, ModalOverlay is z-40 */} {habit ? t(isTask ? 'editTaskTitle' : 'editHabitTitle') : t(isTask ? 'addNewTaskTitle' : 'addNewHabitTitle')}
setName(e.target.value)} required /> { setName(prev => { const space = prev.length > 0 && !prev.endsWith(' ') ? ' ' : ''; return `${prev}${space}${emoji}`; }) }} />
ohsimpson