diff --git a/thoughts-frontend/app/thoughts/[thoughtId]/page.tsx b/thoughts-frontend/app/thoughts/[thoughtId]/page.tsx
index 4499496..664972f 100644
--- a/thoughts-frontend/app/thoughts/[thoughtId]/page.tsx
+++ b/thoughts-frontend/app/thoughts/[thoughtId]/page.tsx
@@ -70,7 +70,7 @@ export default async function ThoughtPage({ params }: ThoughtPageProps) {
return (
- Conversation
+ Thoughts
(
-
+
Top Friends
-
- field.onChange(
- e.target.value.split(",").map((s) => s.trim())
- )
- }
+
- A comma-separated list of usernames.
+ Select up to 8 of your friends to display on your profile.
diff --git a/thoughts-frontend/components/thought-card.tsx b/thoughts-frontend/components/thought-card.tsx
index 3e4dd3c..2ee86a0 100644
--- a/thoughts-frontend/components/thought-card.tsx
+++ b/thoughts-frontend/components/thought-card.tsx
@@ -112,14 +112,14 @@ export function ThoughtCard({
{timeAgo}
- {isAuthor && (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ {isAuthor && (
setIsAlertOpen(true)}
@@ -127,9 +127,15 @@ export function ThoughtCard({
Delete
-
-
- )}
+ )}
+
+
+
+ View
+
+
+
+
{thought.content}
diff --git a/thoughts-frontend/components/top-friends-combobox.tsx b/thoughts-frontend/components/top-friends-combobox.tsx
new file mode 100644
index 0000000..0d0b92f
--- /dev/null
+++ b/thoughts-frontend/components/top-friends-combobox.tsx
@@ -0,0 +1,105 @@
+"use client";
+
+import * as React from "react";
+import { Check, ChevronsUpDown } from "lucide-react";
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import { getFriends, User } from "@/lib/api";
+import { useAuth } from "@/hooks/use-auth";
+import { Skeleton } from "./ui/skeleton";
+
+interface TopFriendsComboboxProps {
+ value: string[];
+ onChange: (value: string[]) => void;
+}
+
+export function TopFriendsCombobox({
+ value,
+ onChange,
+}: TopFriendsComboboxProps) {
+ const [open, setOpen] = React.useState(false);
+ const [friends, setFriends] = React.useState([]);
+ const [isLoading, setIsLoading] = React.useState(true);
+ const { token } = useAuth();
+
+ React.useEffect(() => {
+ if (token) {
+ getFriends(token)
+ .then((data) => setFriends(data.users))
+ .catch(() => console.error("Failed to fetch friends"))
+ .finally(() => setIsLoading(false));
+ } else {
+ setIsLoading(false);
+ }
+ }, [token]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
+
+
+
+ {value.length > 0
+ ? `${value.length} friend(s) selected`
+ : "Select up to 8 friends..."}
+
+
+
+
+
+
+
+ No friends found.
+
+ {friends.map((friend) => (
+ {
+ const newValue = value.includes(currentValue)
+ ? value.filter((v) => v !== currentValue)
+ : [...value, currentValue];
+
+ if (newValue.length <= 8) {
+ onChange(newValue);
+ }
+ }}
+ >
+
+ {friend.username}
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/thoughts-frontend/lib/api.ts b/thoughts-frontend/lib/api.ts
index 7cee691..94d0b7c 100644
--- a/thoughts-frontend/lib/api.ts
+++ b/thoughts-frontend/lib/api.ts
@@ -224,4 +224,12 @@ export const getFollowersList = (username: string, token: string | null) =>
{},
z.object({ users: z.array(UserSchema) }),
token
+ );
+
+ export const getFriends = (token: string) =>
+ apiFetch(
+ "/friends",
+ {},
+ z.object({ users: z.array(UserSchema) }),
+ token
);
\ No newline at end of file