-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(occurrence page): add bookmark button to occurrence page to allo…
…w users to bookmark occurrences, closes #36 feat(bookmark button): add bookmark button component to allow users to bookmark or remove bookmark from an occurrence feat(occurrence actions): add functions to create and remove occurrence bookmarks and revalidate bookmarks page after bookmarking or removing bookmark from an occurrence refactor(occurrenceBookmarks.ts): rename interface OccurrenceBookmarkWithOccurrenceAndProject to OccurrenceBookmarkWithAssociations to improve semantics feat(occurrenceBookmarks.ts): add checkOccurrenceBookmarkExistence function to check if a bookmark exists for a given user and occurrence ID
- Loading branch information
1 parent
2e2b964
commit e5b8f61
Showing
5 changed files
with
119 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,54 @@ | ||
'use client'; | ||
|
||
import { useEffect, useState } from 'react'; | ||
import { useState } from 'react'; | ||
import { BsBookmarkPlus, BsBookmarkStarFill } from 'react-icons/bs'; | ||
|
||
interface BookmarkButtonProps { | ||
projectId: string; | ||
noticeId: string; | ||
occurrenceId: string; | ||
isBookmarked: boolean; | ||
serverAction: (occurrenceId: string) => Promise<void>; | ||
} | ||
|
||
export default function BookmarkButton({ projectId, noticeId, occurrenceId }: BookmarkButtonProps) { | ||
const [isBookmarked, setIsBookmarked] = useState<boolean>(false); | ||
export default function BookmarkButton({ occurrenceId, isBookmarked, serverAction }: BookmarkButtonProps) { | ||
const [isHovered, setIsHovered] = useState(false); | ||
|
||
useEffect(() => { | ||
const storedBookmarks = localStorage.getItem('bookmarks'); | ||
if (storedBookmarks) { | ||
const bookmarks = JSON.parse(storedBookmarks, (key, value) => | ||
key === '' ? value : typeof value === 'string' ? BigInt(value) : value | ||
); | ||
setIsBookmarked( | ||
bookmarks.some((bookmark: any) => { | ||
return ( | ||
bookmark.projectId === projectId && bookmark.noticeId === noticeId && bookmark.occurrenceId === occurrenceId | ||
); | ||
}) | ||
); | ||
} | ||
}, [projectId, noticeId, occurrenceId]); | ||
|
||
const handleBookmark = () => { | ||
const storedBookmarks = localStorage.getItem('bookmarks'); | ||
let bookmarks = []; | ||
if (storedBookmarks) { | ||
bookmarks = JSON.parse(storedBookmarks, (key, value) => | ||
key === '' ? value : typeof value === 'string' ? BigInt(value) : value | ||
); | ||
} | ||
|
||
const bookmarkId = { | ||
projectId: String(projectId), | ||
noticeId: String(noticeId), | ||
occurrenceId: String(occurrenceId), | ||
}; | ||
|
||
const bookmarkIndex = bookmarks.findIndex((bookmark: any) => { | ||
return ( | ||
bookmark.projectId === projectId && bookmark.noticeId === noticeId && bookmark.occurrenceId === occurrenceId | ||
); | ||
}); | ||
const handleToggleBookmark = () => { | ||
serverAction(occurrenceId); | ||
}; | ||
|
||
if (bookmarkIndex !== -1) { | ||
bookmarks.splice(bookmarkIndex, 1); | ||
} else { | ||
bookmarks.push(bookmarkId); | ||
} | ||
const handleMouseEnter = () => { | ||
setIsHovered(true); | ||
}; | ||
|
||
localStorage.setItem('bookmarks', JSON.stringify(bookmarks)); | ||
setIsBookmarked(!isBookmarked); | ||
const handleMouseLeave = () => { | ||
setIsHovered(false); | ||
}; | ||
|
||
return ( | ||
<button | ||
type="button" | ||
onClick={handleBookmark} | ||
className={`inline-flex items-center gap-x-1.5 rounded-md px-3 py-2 text-sm font-semibold ${ | ||
isBookmarked ? 'bg-indigo-900 text-white' : 'bg-indigo-200 text-indigo-900' | ||
} hover:bg-indigo-800 hover:text-white`} | ||
onClick={handleToggleBookmark} | ||
onMouseEnter={handleMouseEnter} | ||
onMouseLeave={handleMouseLeave} | ||
className="inline-flex items-center gap-x-1.5 rounded-md py-2 text-sm font-semibold text-indigo-900" | ||
> | ||
{isBookmarked ? 'Bookmarked' : 'Bookmark'} | ||
{isBookmarked ? ( | ||
<> | ||
{isHovered ? ( | ||
<BsBookmarkPlus className="h-5 w-5 text-indigo-400" aria-hidden="true" /> | ||
) : ( | ||
<BsBookmarkStarFill className="h-5 w-5 text-indigo-400" aria-hidden="true" /> | ||
)} | ||
</> | ||
) : ( | ||
<> | ||
{isHovered ? ( | ||
<BsBookmarkStarFill className="h-5 w-5 text-indigo-400" aria-hidden="true" /> | ||
) : ( | ||
<BsBookmarkPlus className="h-5 w-5 text-indigo-400" aria-hidden="true" /> | ||
)} | ||
</> | ||
)} | ||
</button> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters