From 5aa83ba312ec1600527bdd1543ab3187f56f239c Mon Sep 17 00:00:00 2001 From: shadrach Date: Sat, 19 Oct 2024 00:50:28 -0500 Subject: [PATCH] fix: users search, attestation enhancements --- .../molecules/CommunityAttestations.tsx | 79 ++++--- src/components/molecules/CommunityMembers.tsx | 198 +++++++++++++++++ src/components/organisms/CommunityDetails.tsx | 206 ++---------------- src/lib/tags.ts | 3 +- 4 files changed, 267 insertions(+), 219 deletions(-) create mode 100644 src/components/molecules/CommunityMembers.tsx diff --git a/src/components/molecules/CommunityAttestations.tsx b/src/components/molecules/CommunityAttestations.tsx index bd99def..27f7909 100644 --- a/src/components/molecules/CommunityAttestations.tsx +++ b/src/components/molecules/CommunityAttestations.tsx @@ -19,6 +19,14 @@ import { CommandItem, CommandList, } from "@/components/ui/command"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Check, X, Award, Plus, Settings, Lock, Pen } from "lucide-react"; import { cn } from "@/lib/utils"; import { @@ -29,20 +37,21 @@ import { removeEntryAttestation, } from "@/lib/api"; import Link from "next/link"; -import { buttonVariants } from "../custom/LoaderButton"; +import { buttonVariants, LoaderButton } from "../custom/LoaderButton"; import { useMutation, useQuery, useSuspenseQuery } from "@tanstack/react-query"; +import { DotsHorizontalIcon } from "@radix-ui/react-icons"; +import { useRouter } from "next/navigation"; export default function CommunityAttestations({ community, }: { community: Community; }) { + const router = useRouter(); const [attestationOpen, setAttestationOpen] = useState(false); const { data: attestations, - isLoading, - isError, refetch: refetchCommunityAttestations, } = useQuery(attestationQueryOptions(community.id)); const { data: allAttestations, refetch: refetchAttestations } = @@ -90,10 +99,10 @@ export default function CommunityAttestations({ }; const isPending = addEntryMutation.isPending || removeEntryMutation.isPending; - const hasError = addEntryMutation.isError || removeEntryMutation.isError; - const error = addEntryMutation.error || removeEntryMutation.error; + // const hasError = addEntryMutation.isError || removeEntryMutation.isError; + // const error = addEntryMutation.error || removeEntryMutation.error; - console.log("states", { isPending, hasError, error }); + // console.log("states", { isPending, hasError, error }); return ( @@ -185,28 +194,42 @@ export default function CommunityAttestations({
- - {attestation.isRequired && ( - - )} - {!attestation.isExternal && ( - - - Edit attestation - - )} + + + + + Open menu + + + + + router.push( + `${attestation.communityId}/attestations/${attestation.attestationId}/edit` + ) + } + > + Edit + Edit + + {attestation.isRequired && ( + <> + + + toggleEntryAttestation(attestation.attestationId) + } + > + Delete + ⌘⌫ + + + )} + +
))} diff --git a/src/components/molecules/CommunityMembers.tsx b/src/components/molecules/CommunityMembers.tsx new file mode 100644 index 0000000..f32dad9 --- /dev/null +++ b/src/components/molecules/CommunityMembers.tsx @@ -0,0 +1,198 @@ +"use client"; + +/* eslint-disable @next/next/no-img-element */ +import { useEffect, useState } from "react"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command"; +import { Check, ChevronsUpDown, X, Settings } from "lucide-react"; +import { + addMember, + Community, + removeMember, + searchUsers, +} from "@/lib/api"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import { getQueryClient } from "@/lib/get-query-client"; +import { tags } from "@/lib/tags"; + +type User = { + id: number; + name: string; +}; + +export default function CommunityMembers({ + community, +}: { + community: Community; +}) { + const queryClient = getQueryClient(); + + const members = community.CommunityMember; + const [search, setSearch] = useState(""); + const [open, setOpen] = useState(false); + const [users, setUsers] = useState([]) + + const addMemberMutation = useMutation( + { + mutationFn: addMember, + }, + queryClient + ); + const removeMemberMutation = useMutation( + { + mutationFn: removeMember, + }, + queryClient + ); + + const toggleMember = async (user: User) => { + const existingMember = members.find((m) => m.userId === user.id); + if (existingMember) { + removeMemberMutation.mutate( + { + communityId: community.id, + memberId: existingMember.id, + }, + { + onSuccess() { + queryClient.invalidateQueries({ queryKey: [tags.communities] }); + removeMemberMutation.reset(); + }, + } + ); + } else { + addMemberMutation.mutate( + { communityId: community.id, userId: user.id, role: "MEMBER" }, + { + onSuccess() { + queryClient.invalidateQueries({ queryKey: [tags.communities] }); + }, + } + ); + } + }; + + const { mutate } = useMutation( + { + mutationKey: [tags.users], + mutationFn: searchUsers, + }, + queryClient + ); + + useEffect(() => { + mutate({ name: search.trim()}, { onSuccess(data, variables, context) { + console.log('Results', { data, variables, context}) + if (data?.length > 0) setUsers(data ?? []) + },}) + }, [search, mutate]) + +// const isPending = +// addMemberMutation.isPending || removeMemberMutation.isPending; + + console.log('Users', users) + return ( + + +
+ Members + + {community.CommunityMember?.length ?? "No"} members + +
+ + + + + + + Manage Members + + + setSearch(search)} + /> + + No users found. + + {users?.map((user) => ( + toggleMember(user)} + className="flex items-center justify-between" + > + {user.name} + {members.some((m) => m.userId === user.id) && ( + + )} + + ))} + + + + + +
+ + + {members.map((member) => ( +
+
+ + {member.user.name[0]} + +
+

{member.user.name}

+

{member.role}

+
+
+ +
+ ))} +
+
+
+ ); +} diff --git a/src/components/organisms/CommunityDetails.tsx b/src/components/organisms/CommunityDetails.tsx index e13dae8..af140aa 100644 --- a/src/components/organisms/CommunityDetails.tsx +++ b/src/components/organisms/CommunityDetails.tsx @@ -2,51 +2,22 @@ /* eslint-disable @next/next/no-img-element */ import { useState } from "react"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; -import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; -import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, -} from "@/components/ui/command"; -import { - Check, - ChevronsUpDown, ExternalLink, ThumbsUp, MessageSquare, CheckCircle, - X, - Settings, + Pen, } from "lucide-react"; -import { addMember, Community, removeMember, searchUsers } from "@/lib/api"; +import { Community } from "@/lib/api"; import ExpandableMarkdown from "@/components/molecules/ExpandableMarkdown"; import CommunityAttestations from "@/components/molecules/CommunityAttestations"; -import { useMutation, useQuery } from "@tanstack/react-query"; -import { NODES_API_URL } from "@/lib/config"; -import { getQueryClient } from "@/lib/get-query-client"; -import axios from "axios"; -import { tags } from "@/lib/tags"; +import CommunityMembers from "../molecules/CommunityMembers"; +import { Button } from "../ui/button"; +import { useRouter } from "next/navigation"; type User = { id: number; @@ -65,15 +36,8 @@ type CommunityProps = { allAttestations: AttestationVersion[]; }; -export default function Component({ - community, - users, - allAttestations, -}: CommunityProps) { - const [open, setOpen] = useState(false); - const [members, setMembers] = useState(() => community.CommunityMember ?? []); - - console.log({ users, allAttestations }); +export default function Component({ community }: CommunityProps) { + const router = useRouter(); return (
@@ -90,7 +54,13 @@ export default function Component({ />
-

{community.name}

+
+

{community.name}

+ +

{community.subtitle}

@@ -178,7 +148,7 @@ export default function Component({
- + @@ -259,147 +229,3 @@ export default function Component({
); } - -function CommunityMember({ community }: { community: Community }) { - const queryClient = getQueryClient(); - - const members = community.CommunityMember; - const [search, setSearch] = useState(); - const [open, setOpen] = useState(false); - - const addMemberMutation = useMutation( - { - mutationFn: addMember, - }, - queryClient - ); - const removeMemberMutation = useMutation( - { - mutationFn: removeMember, - }, - queryClient - ); - - const toggleMember = async (user: User) => { - console.log("toggle", user); - const existingMember = members.find((m) => m.userId === user.id); - if (existingMember) { - removeMemberMutation.mutate( - { - communityId: community.id, - memberId: existingMember.id, - }, - { - onSuccess() { - queryClient.invalidateQueries({ queryKey: [tags.communities] }); - removeMemberMutation.reset(); - }, - } - ); - } else { - addMemberMutation.mutate( - { communityId: community.id, userId: user.id, role: "MEMBER" }, - { - onSuccess() { - queryClient.invalidateQueries({ queryKey: [tags.communities] }); - }, - } - ); - } - }; - - const { - data: users, - isLoading, - isError, - } = useQuery({ - queryKey: ["users/search"], - queryFn: () => searchUsers({ name: search }), - // enabled: !!search, - }); - - return ( - - -
- Members - - {community.CommunityMember?.length ?? "No"} members - -
- - - {/* */} - - - - - Manage Community Members - - - setSearch(search)} - /> - - No users found. - - {users?.map((user) => ( - toggleMember(user)} - className="flex items-center justify-between" - > - {user.name} - {members.some((m) => m.userId === user.id) ? ( - - ) : ( - - )} - - ))} - - - - - -
- - - {members.map((member) => ( -
-
- - {member.user.name[0]} - -
-

{member.user.name}

-

{member.role}

-
-
- -
- ))} -
-
-
- ); -} diff --git a/src/lib/tags.ts b/src/lib/tags.ts index f718460..8177984 100644 --- a/src/lib/tags.ts +++ b/src/lib/tags.ts @@ -1,4 +1,5 @@ export enum tags { communities = 'communities', - attestations = 'attestations' + attestations = 'attestations', + users = 'users', } \ No newline at end of file