import React, { useCallback, useMemo, useState } from "react" import Link from "next/link" import { useRouter } from "next/navigation" import { useAtom } from "jotai" import { toast } from "sonner" import { LaIcon } from "@/components/custom/la-icon" import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover" import { Button } from "@/components/ui/button" import { LearningStateSelectorContent } from "@/components/custom/learning-state-selector" import { cn, ensureUrlProtocol, generateUniqueSlug } from "@/lib/utils" import { LaAccount, Link as LinkSchema, PersonalLink, PersonalLinkLists, Topic, UserRoot } from "@/lib/schema" import { openPopoverForIdAtom } from "../TopicDetailRoute" import { LEARNING_STATES, LearningStateValue } from "@/lib/constants" interface LinkItemProps { topic: Topic link: LinkSchema isActive: boolean index: number setActiveIndex: (index: number) => void me: { root: { personalLinks: PersonalLinkLists } & UserRoot } & LaAccount personalLinks: PersonalLinkLists } export const LinkItem = React.memo( React.forwardRef( ({ topic, link, isActive, index, setActiveIndex, me, personalLinks }, ref) => { const router = useRouter() const [, setOpenPopoverForId] = useAtom(openPopoverForIdAtom) const [isPopoverOpen, setIsPopoverOpen] = useState(false) const personalLink = useMemo(() => { return personalLinks.find(pl => pl?.link?.id === link.id) }, [personalLinks, link.id]) const selectedLearningState = useMemo(() => { return LEARNING_STATES.find(ls => ls.value === personalLink?.learningState) }, [personalLink?.learningState]) const handleClick = useCallback( (e: React.MouseEvent) => { e.preventDefault() setActiveIndex(index) }, [index, setActiveIndex] ) const handleSelectLearningState = useCallback( (learningState: LearningStateValue) => { const defaultToast = { duration: 5000, position: "bottom-right" as const, closeButton: true, action: { label: "Go to list", onClick: () => router.push("/") } } if (personalLink) { if (personalLink.learningState === learningState) { personalLink.learningState = undefined toast.error("Link learning state removed", defaultToast) } else { personalLink.learningState = learningState toast.success("Link learning state updated", defaultToast) } } else { const slug = generateUniqueSlug(personalLinks.toJSON(), link.title) const newPersonalLink = PersonalLink.create( { url: link.url, title: link.title, slug, link, learningState, sequence: personalLinks.length + 1, completed: false, topic, createdAt: new Date(), updatedAt: new Date() }, { owner: me } ) personalLinks.push(newPersonalLink) toast.success("Link added.", { ...defaultToast, description: `${link.title} has been added to your personal link.` }) } setOpenPopoverForId(null) setIsPopoverOpen(false) }, [personalLink, personalLinks, me, link, router, setOpenPopoverForId, topic] ) const handlePopoverOpenChange = useCallback( (open: boolean) => { setIsPopoverOpen(open) setOpenPopoverForId(open ? link.id : null) }, [link.id, setOpenPopoverForId] ) return (
  • e.preventDefault()} > handleSelectLearningState(value as LearningStateValue)} />

    {link.title}

  • ) } ) ) LinkItem.displayName = "LinkItem"