Skip to content

Commit

Permalink
Add profile drawer to conversations
Browse files Browse the repository at this point in the history
  • Loading branch information
FosterChad95 committed Jul 20, 2023
1 parent 6e96a2b commit aad9701
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 28 deletions.
2 changes: 0 additions & 2 deletions app/components/sidebar/DesktopSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const DesktopSidebar: React.FC<DesktopSidebarProps> = ({ currentUser }) => {
const routes = useRoutes();
const [isOpen, setIsOpen] = useState(false);

console.log(currentUser);

return (
<div
className="hidden lg:fixed
Expand Down
60 changes: 35 additions & 25 deletions app/conversations/[conversationId]/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import Avatar from "@/app/components/Avatar";
import useOtherUser from "@/app/hooks/useOtherUser";
import { Conversation, User } from "@prisma/client";
import Link from "next/link";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { HiChevronLeft } from "react-icons/hi";
import { HiEllipsisHorizontal } from "react-icons/hi2";
import ProfileDrawer from "./ProfileDrawer";

interface HeaderProps {
conversation: Conversation & {
Expand All @@ -15,6 +16,8 @@ interface HeaderProps {
}

const Header: React.FC<HeaderProps> = ({ conversation }) => {
const [drawerOpen, setDrawerOpen] = useState(false);

const otherUser = useOtherUser(conversation);

const statusText = useMemo(() => {
Expand All @@ -26,8 +29,14 @@ const Header: React.FC<HeaderProps> = ({ conversation }) => {
}, [conversation]);

return (
<div
className="
<>
<ProfileDrawer
data={conversation}
isOpen={drawerOpen}
onClose={() => setDrawerOpen(false)}
/>
<div
className="
bg-white
w-full
flex
Expand All @@ -39,43 +48,44 @@ const Header: React.FC<HeaderProps> = ({ conversation }) => {
justify-between
items-center
shadow-sm"
>
<div className="flex gap-3 items-center">
<Link
href="/conversations"
className="
>
<div className="flex gap-3 items-center">
<Link
href="/conversations"
className="
lg:hidden
block
text-sky-500
hover:text-sky-600
transition
cursor-pointer"
>
<HiChevronLeft size={32} />
</Link>
<Avatar user={otherUser} />
<div className="flex flex-col">
<div>{conversation.name || otherUser.name}</div>
<div
className="
>
<HiChevronLeft size={32} />
</Link>
<Avatar user={otherUser} />
<div className="flex flex-col">
<div>{conversation.name || otherUser.name}</div>
<div
className="
text-sm
font-light
text-neutral-500"
>
{statusText}
>
{statusText}
</div>
</div>
</div>
</div>
<HiEllipsisHorizontal
size={32}
onClick={() => {}}
className="
<HiEllipsisHorizontal
size={32}
onClick={() => setDrawerOpen(true)}
className="
text-sky-500
cursor-pointer
hover:text-sky-600
transition"
/>
</div>
/>
</div>
</>
);
};

Expand Down
282 changes: 282 additions & 0 deletions app/conversations/[conversationId]/components/ProfileDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
"use client";

import Avatar from "@/app/components/Avatar";
import useOtherUser from "@/app/hooks/useOtherUser";
import { Dialog, Transition } from "@headlessui/react";
import { Conversation, User } from "@prisma/client";
import { format } from "date-fns";
import { Fragment, useMemo } from "react";
import { IoClose, IoTrash } from "react-icons/io5";

interface ProfileDrawerProps {
isOpen: boolean;
onClose: () => void;
data: Conversation & {
users: User[];
};
}

const ProfileDrawer: React.FC<ProfileDrawerProps> = ({
isOpen,
onClose,
data,
}) => {
const otherUser = useOtherUser(data);

const joinedDate = useMemo(() => {
return format(new Date(otherUser.createdAt), "PP");
}, [otherUser.createdAt]);

const title = useMemo(() => {
return data.name || otherUser.name;
}, [data.name, otherUser.name]);

const statusText = useMemo(() => {
if (data.isGroup) {
return `${data.users.length} members`;
}

return "Active";
}, [data]);

return (
<Transition.Root show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-50" onClose={onClose}>
<Transition.Child
as={Fragment}
enter="ease-out duration-500"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-500"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
className="
fixed
inset-0
bg-black
bg-opacity-40"
></div>
</Transition.Child>
<div
className="
fixed
inset-0
overflow-hidden"
>
<div
className="
absolute
inset-0
overflow-hidden"
>
<div
className="
pointer-events-none
fixed
inset-y-0
right-0
flex
max-w-full
pl-10"
>
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-500"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-500"
leaveTo="translate-x-full"
>
<Dialog.Panel
className="
pointer-events-auto
w-screen
max-w-md"
>
<div
className="
flex
h-full
flex-col
overflow-y-scroll
bg-white
py-6
shadow-xl"
>
<div className="px-4 sm:px-6">
<div
className="
flex
items-start
justify-end"
>
<div
className="
ml-3
flex
h-7
items-center"
>
<button
type="button"
className="
rounded-md
bg-white
text-gray-400
hover:text-gray-500
focus:outline-none
focus:ring-2
focus:ring-sky-500
focus:ring-offset-2"
onClick={onClose}
>
<span className="sr-only">Close panel</span>
<IoClose size={24} />
</button>
</div>
</div>
</div>
<div
className="
relative
mt-6
flex-1
px-4
sm:px-6"
>
<div
className="
flex
flex-col
items-center"
>
<div className="mb-2">
<Avatar user={otherUser} />
</div>
<div>{title}</div>
<div
className="
text-sm
text-gray-500
"
>
{statusText}
</div>
<div className="flex gap-10 my-8">
<div
onClick={() => {}}
className="
flex
flex-col
gap-3
items-center
cursor-pointer
hover:opacity-75"
>
<div
className="
w-10
h-10
bg-neutral-100
rounded-full
flex
items-center
justify-center"
>
<IoTrash size={20} />
</div>
<div
className="
text-sm
font-light
text-neutral-600"
>
Delete
</div>
</div>
</div>
<div
className="
w-full
pb-5
pt-5
sm:px-0
sm:pt-0"
>
<dl
className="
space-y-8
px-4
sm:space-y-6
sm:px-6"
>
{!data.isGroup && (
<div>
<dt
className="
text-sm
font-medium
text-gray-500
sm:w-40
sm:flex-shrink-0"
>
Email
</dt>
<dd
className="
mt-1
text-sm
text-gray-900
sm:col-span-2"
>
{otherUser.email}
</dd>
</div>
)}
{!data.isGroup && (
<>
<hr />
<div>
<dt
className="
text-sm
font-medium
text-gray-500
sm:w-40
sm:flex-shrink-0
"
>
Joined
</dt>
<dd
className="
mt-1
text-sm
text-gray-900
sm:col-span-2"
>
<time dateTime={joinedDate}>
{joinedDate}
</time>
</dd>
</div>
</>
)}
</dl>
</div>
</div>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</div>
</Dialog>
</Transition.Root>
);
};

export default ProfileDrawer;
Loading

0 comments on commit aad9701

Please sign in to comment.