import { useState, useContext, useCallback, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import {
Card,
Button,
Space,
Typography,
Flex,
Tag,
Dropdown,
Divider,
Modal
} from 'antd'
import { CaretLeftFilled, LoadingOutlined } from '@ant-design/icons'
import PlusIcon from '../../Icons/PlusIcon'
import BinIcon from '../../Icons/BinIcon'
import PersonIcon from '../../Icons/PersonIcon'
import TimeDisplay from './TimeDisplay'
import MarkdownDisplay from './MarkdownDisplay'
import IdDisplay from './IdDisplay'
import MissingPlaceholder from './MissingPlaceholder'
import NewNote from '../Management/Notes/NewNote'
import { ApiServerContext } from '../context/ApiServerContext'
import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon'
import UserNotifierToggle from './UserNotifierToggle'
import { AuthContext } from '../context/AuthContext'
import { getModelByName } from '../../../database/ObjectModels'
import { useNavigate } from 'react-router-dom'
const { Text } = Typography
const NoteItem = ({
note,
showCard = true,
showCreatedAt = true,
showChildNotes = true,
showActions = true,
showInfo = true,
largeSpacing = false
}) => {
const [childNotes, setChildNotes] = useState([])
const noteModel = getModelByName('note')
const infoAction = noteModel.actions.filter(
(action) => action.name == 'info'
)[0]
const InfoIcon = infoAction.icon
const [newNoteOpen, setNewNoteOpen] = useState(false)
const [deleteNoteOpen, setDeleteNoteOpen] = useState(false)
const [deleteNoteLoading, setDeleteNoteLoading] = useState(false)
const [childNotesLoading, setChildNotesLoading] = useState(false)
const [isExpanded, setIsExpanded] = useState(false)
const subscribeToObjectTypeUpdatesRef = useRef(null)
const navigate = useNavigate()
const {
deleteObject,
fetchObjects,
subscribeToObjectTypeUpdates,
connected
} = useContext(ApiServerContext)
const { userProfile, token } = useContext(AuthContext)
let transformValue = 'rotate(0deg)'
if (isExpanded) {
transformValue = 'rotate(-90deg)'
}
const handleNoteExpand = useCallback(async () => {
setChildNotesLoading(true)
try {
const childNotesData = await fetchObjects('note', {
filter: { 'parent._id': note._id }
})
setChildNotes(childNotesData.data)
} catch (error) {
console.error('Error fetching child notes:', error)
} finally {
setChildNotesLoading(false)
}
}, [note._id, fetchObjects])
const toggleExpand = async () => {
if (isExpanded == false) {
await handleNoteExpand()
setIsExpanded(true)
} else {
setChildNotes([])
setIsExpanded(false)
}
}
const handleDeleteNote = async () => {
if (token != null) {
setDeleteNoteLoading(true)
await deleteObject(note._id, 'note')
setDeleteNoteOpen(false)
setDeleteNoteLoading(false)
}
}
useEffect(() => {
if (connected == true && subscribeToObjectTypeUpdatesRef.current == null) {
if (isExpanded == true) {
subscribeToObjectTypeUpdatesRef.current = subscribeToObjectTypeUpdates(
'note',
(noteData) => {
if (noteData.parent._id == note._id) {
if (isExpanded == true) {
handleNoteExpand()
}
}
}
)
} else {
if (subscribeToObjectTypeUpdatesRef.current) {
subscribeToObjectTypeUpdatesRef.current()
subscribeToObjectTypeUpdatesRef.current = null
}
}
}
return () => {
if (connected == true && subscribeToObjectTypeUpdatesRef.current) {
subscribeToObjectTypeUpdatesRef.current()
subscribeToObjectTypeUpdatesRef.current = null
}
}
}, [
subscribeToObjectTypeUpdates,
connected,
handleNoteExpand,
isExpanded,
note._id
])
// Check if the current user can delete this note
const canDeleteNote = userProfile && userProfile._id === note.user._id
const dropdownItems = [
{
key: 'new',
icon: ,
label: 'New Note',
onClick: () => {
setNewNoteOpen(true)
}
}
]
// Only add delete option if user owns the note
if (canDeleteNote) {
dropdownItems.push({
key: 'delete',
label: 'Delete Note',
icon: ,
onClick: () => {
setDeleteNoteOpen(true)
},
danger: true
})
}
const noteItem = (
<>
{note.user.name}:
{showActions && (
<>
>
)}
Type:
{note.noteType.name}
User ID:
{showCreatedAt && (
Created At:
)}
{showInfo && (
}
type='text'
size='small'
onClick={() => {
navigate(infoAction.url(note._id))
}}
/>
)}
{showChildNotes && (
) : (
)
}
size='small'
type='text'
loading={childNotesLoading}
disabled={childNotesLoading}
style={{
transform: transformValue,
transition: 'transform 0.2s ease'
}}
onClick={toggleExpand}
/>
)}
{isExpanded && (
{childNotes.length > 0 ? (
childNotes.map((childNote) => (
))
) : (
)}
)}
{
setNewNoteOpen(false)
}}
width={800}
closeIcon={false}
destroyOnHidden={true}
footer={null}
>
{
setNewNoteOpen(false)
}}
defaultValues={{
parent: { _id: note._id },
parentType: 'note'
}}
/>
Confirm Delete
}
okText='Delete'
cancelText='Cancel'
okType='danger'
closable={false}
centered
maskClosable={false}
footer={[
,
]}
>
Are you sure you want to delete this note?
>
)
return showCard ? (
{noteItem}
) : (
noteItem
)
}
NoteItem.propTypes = {
note: PropTypes.object.isRequired,
showCard: PropTypes.bool,
showCreatedAt: PropTypes.bool,
showChildNotes: PropTypes.bool,
showActions: PropTypes.bool,
largeSpacing: PropTypes.bool,
showInfo: PropTypes.bool
}
export default NoteItem