Skip to content

Commit

Permalink
Merge pull request #818 from bounswe/FRONTEND-809
Browse files Browse the repository at this point in the history
feat(frontend): implement bookmark word functionality
  • Loading branch information
yunusemreozdemir authored Dec 14, 2024
2 parents 03710ef + 5c1029a commit ca0e0e2
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 4 deletions.
75 changes: 74 additions & 1 deletion frontend/src/components/common/dictionary-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@ import {
ModalContent,
ModalBody,
ScrollShadow,
Button,
} from "@nextui-org/react";
import { IconBookmark, IconBookmarkFilled } from "@tabler/icons-react";
import { useState, useEffect } from "react";
import axios from "axios";
import { BASE_URL } from "../../lib/baseURL";
import ClickableText from "./clickable-text";
import { AuthActions } from "../auth/utils";
import GuestAuthModal from "../auth/guest-auth-modal";

export default function DictionaryModal({ isOpen, setIsOpen, word }) {
const [meanings, setMeanings] = useState([]);
const [translations, setTranslations] = useState([]);
const [isBookmarked, setIsBookmarked] = useState(false);
const [guestModalOpen, setGuestModalOpen] = useState(false);
const { getToken } = AuthActions();
const token = getToken("access");
const isGuest = !token;

useEffect(() => {
if (!word) {
Expand All @@ -33,6 +42,43 @@ export default function DictionaryModal({ isOpen, setIsOpen, word }) {
console.log(error);
});
}, [word]);

useEffect(() => {
if (!word) {
return;
}
axios
.get(`${BASE_URL}/word/bookmarks/`, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((response) => {
console.log(response.data);
setIsBookmarked(response.data.bookmarked_words.includes(word));
})
.catch((error) => {
console.log(error);
});
}, [word, token]);

const toggleBookmark = () => {
axios
.post(
`${BASE_URL}/word/${isBookmarked ? "unbookmark" : "bookmark"}/${word}/`,
{},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
)
.then((response) => {
console.log(response.data);
setIsBookmarked(!isBookmarked);
});
};

return (
<Modal
isOpen={isOpen}
Expand All @@ -43,7 +89,34 @@ export default function DictionaryModal({ isOpen, setIsOpen, word }) {
>
{word && (
<ModalContent className="pb-6 gap-3">
<ModalHeader>{word.match(/[a-zA-Z]+/g).join(" ")}</ModalHeader>
<ModalHeader>
<div className="flex items-center gap-2">
<div>{word.match(/[a-zA-Z]+/g).join(" ")}</div>
<Button
isIconOnly
color="secondary"
aria-label="Bookmark"
onClick={
isGuest
? () => {
setGuestModalOpen(true);
}
: toggleBookmark
}
variant="light"
>
{isBookmarked ? (
<IconBookmarkFilled size={20} stroke={1.5} />
) : (
<IconBookmark size={20} stroke={1.5} />
)}
</Button>
<GuestAuthModal
isOpen={guestModalOpen}
setIsOpen={setGuestModalOpen}
/>
</div>
</ModalHeader>
<ModalBody className="text-left text-default-500">
<ScrollShadow className="max-h-[450px]">
<h1 className="text-lg font-semibold text-default-900">
Expand Down
32 changes: 29 additions & 3 deletions frontend/src/pages/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ModalContent,
ModalBody,
ModalHeader,
Card,
} from "@nextui-org/react";
import { useState, useEffect, Suspense } from "react";

Expand Down Expand Up @@ -39,6 +40,7 @@ import Cookies from "js-cookie";
import { usePageTitle } from "../components/common/usePageTitle.ts";
import QuizCard from "../components/quiz/quiz-card.tsx";
import GuestAuthModal from "../components/auth/guest-auth-modal.tsx";
import ClickableText from "../components/common/clickable-text.tsx";

export default function Profile() {
usePageTitle("Profile");
Expand Down Expand Up @@ -214,6 +216,22 @@ export default function Profile() {
});
}, [token]);

useEffect(() => {
axios
.get(`${BASE_URL}/word/bookmarks/`, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((response) => {
console.log(response.data);
setBookmarkedWords(response.data.bookmarked_words);
})
.catch((error) => {
console.log(error);
});
}, [token]);

const toggleFollow = () => {
axios
.post(
Expand Down Expand Up @@ -472,7 +490,7 @@ export default function Profile() {
</div>
}
>
<div className="flex flex-col gap-4 items-center">
<div className="flex flex-col gap-4 items-left w-[740px]">
{bookmarkedPosts.map((post) => (
<Suspense key={post.id} fallback={<PostCardSkeleton />}>
<PostCard
Expand All @@ -499,7 +517,7 @@ export default function Profile() {
</div>
}
>
<div className="flex flex-col gap-4 items-center">
<div className="flex flex-col gap-4 items-left w-[740px]">
{bookmarkedQuizzes.map((quiz) => (
<Suspense key={quiz.id} fallback={<PostCardSkeleton />}>
<QuizCard
Expand Down Expand Up @@ -527,7 +545,15 @@ export default function Profile() {
</div>
}
>
<div className="w-[740px]">Words</div>
<div className="flex flex-col gap-4 items-left w-[740px]">
{bookmarkedWords.map((word, index) => (
<Suspense key={index} fallback={<PostCardSkeleton />}>
<Card className="w-48 px-2 py-2 text-center">
<ClickableText text={word} />
</Card>
</Suspense>
))}
</div>
</Tab>
</Tabs>
</div>
Expand Down

0 comments on commit ca0e0e2

Please sign in to comment.