This commit is contained in:
marshennikovaolga
2024-10-02 18:04:01 +03:00
parent 0b904f4e86
commit 64b435e229
2 changed files with 40 additions and 17 deletions

View File

@@ -6,8 +6,8 @@ import { Button } from "@/components/ui/button"
import { useAccount } from "@/lib/providers/jazz-provider" import { useAccount } from "@/lib/providers/jazz-provider"
import { LaIcon } from "@/components/custom/la-icon" import { LaIcon } from "@/components/custom/la-icon"
import { Checkbox } from "@/components/ui/checkbox" import { Checkbox } from "@/components/ui/checkbox"
import { format } from "date-fns"
import { DatePicker } from "@/components/ui/date-picker" import { DatePicker } from "@/components/ui/date-picker"
import { format, parse } from "date-fns"
interface TaskFormProps { interface TaskFormProps {
filter?: "today" | "upcoming" | undefined filter?: "today" | "upcoming" | undefined
@@ -19,9 +19,14 @@ export const TaskForm: React.FC<TaskFormProps> = ({ filter }) => {
const [inputVisible, setInputVisible] = useState(false) const [inputVisible, setInputVisible] = useState(false)
const { me } = useAccount({ root: {} }) const { me } = useAccount({ root: {} })
const inputRef = useRef<HTMLInputElement>(null) const inputRef = useRef<HTMLInputElement>(null)
const formRef = useRef<HTMLDivElement>(null)
const handleSubmit = (e: React.FormEvent) => { const handleSubmit = (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
saveTask()
}
const saveTask = () => {
if (title.trim() && (filter !== "upcoming" || dueDate)) { if (title.trim() && (filter !== "upcoming" || dueDate)) {
if (me?.root?.tasks === undefined) { if (me?.root?.tasks === undefined) {
if (!me) return if (!me) return
@@ -64,6 +69,23 @@ export const TaskForm: React.FC<TaskFormProps> = ({ filter }) => {
} }
}, [inputVisible]) }, [inputVisible])
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (formRef.current && !formRef.current.contains(event.target as Node)) {
if (title.trim()) {
saveTask()
} else {
resetForm()
}
}
}
document.addEventListener("mousedown", handleClickOutside)
return () => {
document.removeEventListener("mousedown", handleClickOutside)
}
}, [title, dueDate])
const formattedDate = dueDate ? format(dueDate, "EEE, MMMM do, yyyy") : "Select a date" const formattedDate = dueDate ? format(dueDate, "EEE, MMMM do, yyyy") : "Select a date"
return ( return (
@@ -76,7 +98,7 @@ export const TaskForm: React.FC<TaskFormProps> = ({ filter }) => {
initial={{ opacity: 0, width: 0 }} initial={{ opacity: 0, width: 0 }}
animate={{ opacity: 1, width: "auto" }} animate={{ opacity: 1, width: "auto" }}
exit={{ opacity: 0, width: 0 }} exit={{ opacity: 0, width: 0 }}
transition={{ duration: 0.3 }} transition={{ duration: 0.01 }}
> >
<Button <Button
className="flex flex-row items-center gap-1" className="flex flex-row items-center gap-1"
@@ -88,17 +110,13 @@ export const TaskForm: React.FC<TaskFormProps> = ({ filter }) => {
</Button> </Button>
</motion.div> </motion.div>
) : ( ) : (
<motion.form <div
key="input-form" ref={formRef}
initial={{ width: 0, opacity: 0 }}
animate={{ width: "100%", opacity: 1 }}
exit={{ width: 0, opacity: 0 }}
transition={{ duration: 0.3 }}
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="bg-result flex w-full items-center justify-between rounded-lg p-2 px-3" className="bg-result flex w-full items-center justify-between rounded-lg px-2 py-1"
> >
<div className="flex flex-row items-center gap-3"> <div className="flex min-w-0 flex-1 items-center">
<Checkbox checked={false} onCheckedChange={() => {}} /> <Checkbox checked={false} onCheckedChange={() => {}} className="mr-2" />
<Input <Input
autoFocus autoFocus
ref={inputRef} ref={inputRef}
@@ -109,13 +127,17 @@ export const TaskForm: React.FC<TaskFormProps> = ({ filter }) => {
placeholder="Task title" placeholder="Task title"
/> />
</div> </div>
<div className="flex items-center space-x-2">
<div className="ml-2 flex items-center" onClick={e => e.stopPropagation()}>
{filter === "upcoming" && ( {filter === "upcoming" && (
<DatePicker date={dueDate} onDateChange={(date: Date | undefined) => setDueDate(date)} /> <DatePicker
date={dueDate}
onDateChange={(date: Date | undefined) => setDueDate(date)}
className="z-50"
/>
)} )}
<span className="text-muted-foreground text-xs">{formattedDate}</span>
</div> </div>
</motion.form> </div>
) )
) : null} ) : null}
</AnimatePresence> </AnimatePresence>

View File

@@ -17,7 +17,7 @@ export function DatePicker({ date, onDateChange, className }: DatePickerProps) {
const selectDate = (selectedDate: Date | undefined) => { const selectDate = (selectedDate: Date | undefined) => {
onDateChange(selectedDate) onDateChange(selectedDate)
setOpen(false) // Закрываем Popover после выбора даты setOpen(false)
} }
return ( return (
@@ -26,12 +26,13 @@ export function DatePicker({ date, onDateChange, className }: DatePickerProps) {
<Button <Button
variant={"outline"} variant={"outline"}
className={cn("w-[240px] justify-start text-left font-normal", !date && "text-muted-foreground", className)} className={cn("w-[240px] justify-start text-left font-normal", !date && "text-muted-foreground", className)}
onClick={e => e.stopPropagation()}
> >
<CalendarIcon className="mr-2 h-4 w-4" /> <CalendarIcon className="mr-2 h-4 w-4" />
{date ? format(date, "PPP") : <span>Pick a date</span>} {date ? format(date, "PPP") : <span>Pick a date</span>}
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start"> <PopoverContent className="w-auto p-0" align="start" onClick={e => e.stopPropagation()}>
<Calendar mode="single" selected={date} onSelect={selectDate} initialFocus /> <Calendar mode="single" selected={date} onSelect={selectDate} initialFocus />
</PopoverContent> </PopoverContent>
</Popover> </Popover>