Skip to content

Commit

Permalink
Chat Page Design Added
Browse files Browse the repository at this point in the history
  • Loading branch information
sinanptm committed Sep 23, 2024
1 parent 35aedc2 commit c91a00d
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 3 deletions.
68 changes: 68 additions & 0 deletions client/app/(landing-pages)/chats/@chat/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client'

import { ScrollArea } from "@/components/ui/scroll-area"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { useParams, useRouter } from "next/navigation"
import { ButtonV2 } from "@/components/common/ButtonV2"
import { Input } from "@/components/ui/input"
import { useState } from "react"
import { ArrowLeft } from "lucide-react"

const ChatSection = () => {
const { id: userId } = useParams()
const [message, setMessage] = useState("")
const router = useRouter()

if (!userId) {
return <div className="flex items-center justify-center h-full">User not found</div>
}

const handleSendMessage = () => {
console.log("Sending message:", message)
setMessage("")
}

return (
<div className="flex flex-col h-full bg-background">
<header className="p-4 border-b border-border flex-shrink-0">
<div className="flex items-center space-x-4">
<button onClick={() => router.back()} className="sm:hidden">
<ArrowLeft className="h-6 w-6" />
</button>
<Avatar className="w-10 h-10">
<AvatarImage src="/assets/icons/circle-user.svg" alt={`User ${userId}`} />
<AvatarFallback>{userId}</AvatarFallback>
</Avatar>
<h2 className="text-xl font-semibold">Chat with User {userId}</h2>
</div>
</header>
<ScrollArea className="flex-grow p-4">
<div className="space-y-4">
<div className="flex items-end gap-2">
<div className="rounded-lg bg-accent p-3 max-w-[70%]">
<p className="text-sm">Hello, how are you?</p>
</div>
</div>
<div className="flex items-end gap-2 justify-end">
<div className="rounded-lg bg-primary text-primary-foreground p-3 max-w-[70%]">
<p className="text-sm">I'm fine, thanks for asking!</p>
</div>
</div>
</div>
</ScrollArea>
<footer className="border-t border-border p-4 flex-shrink-0">
<div className="flex items-center gap-2">
<Input
className="flex-1"
placeholder={`Message user ${userId}`}
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<ButtonV2 onClick={handleSendMessage}>Send</ButtonV2>
</div>
</footer>
</div>
)
}

export default ChatSection
7 changes: 7 additions & 0 deletions client/app/(landing-pages)/chats/@chat/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function ChatDefault() {
return (
<div className="flex items-center justify-center h-full">
<h2>Select a chat to start messaging.</h2>
</div>
);
}
4 changes: 4 additions & 0 deletions client/app/(landing-pages)/chats/@chatList/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ChatUserList from './page'

export default () => <ChatUserList />

58 changes: 58 additions & 0 deletions client/app/(landing-pages)/chats/@chatList/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'

import { useState } from "react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { ScrollArea } from "@/components/ui/scroll-area"
import Link from "next/link"
import { MoreVertical } from "lucide-react"

interface Contact {
id: number
name: string
lastMessage: string
avatar: string
lastSeen: string
}

export default function ChatList() {
const [selectedId, setSelectedId] = useState<number | null>(null)

const contacts: Contact[] = [
{ id: 1, name: "Alice Johnson", lastMessage: "Hey, how are you?", avatar: "/assets/icons/circle-user.svg", lastSeen: "2m" },
{ id: 2, name: "Bob Smith", lastMessage: "Let's catch up later.", avatar: "/assets/icons/circle-user.svg", lastSeen: "1h" },
{ id: 3, name: "Charlie Brown", lastMessage: "Got the files?", avatar: "/assets/icons/circle-user.svg", lastSeen: "3h" },
{ id: 4, name: "Diana Prince", lastMessage: "Meeting at 3 PM", avatar: "/assets/icons/circle-user.svg", lastSeen: "5h" },
{ id: 5, name: "Ethan Hunt", lastMessage: "Mission accomplished!", avatar: "/assets/icons/circle-user.svg", lastSeen: "1d" },
]

return (
<div className="flex flex-col h-full bg-background">
<ScrollArea className="flex-grow">
<div className="space-y-1 p-1">
{contacts.map(({ id, name, lastMessage, avatar, lastSeen }) => (
<Link href={`/chats/${id}`} key={id} className="block">
<div
className={`flex items-center space-x-2 p-2 rounded-lg transition-colors ${
selectedId === id ? 'bg-accent' : 'hover:bg-accent/50'
}`}
onClick={() => setSelectedId(id)}
>
<Avatar className="w-8 h-8 flex-shrink-0">
<AvatarImage src={avatar} alt={name} />
<AvatarFallback>{name.charAt(0)}</AvatarFallback>
</Avatar>
<div className="min-w-0 flex-1 hidden sm:block">
<div className="flex justify-between items-baseline">
<h3 className="font-medium text-sm truncate">{name}</h3>
<span className="text-xs text-muted-foreground">{lastSeen}</span>
</div>
<p className="text-xs text-muted-foreground truncate">{lastMessage}</p>
</div>
</div>
</Link>
))}
</div>
</ScrollArea>
</div>
)
}
27 changes: 27 additions & 0 deletions client/app/(landing-pages)/chats/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ReactNode } from 'react';

export default function ChatLayout({
chatList,
chat,
}: {
chatList: ReactNode;
chat: ReactNode;
}) {
return (
<div className="flex h-[calc(100vh-4rem)]">
<aside className="w-16 sm:w-64 md:w-80 border-r border-border overflow-hidden flex-shrink-0">
{chatList || <div className="p-4">Loading chat list...</div>}
</aside>
<main className="flex-1 overflow-hidden">
{chat || (
<div className="h-full flex items-center justify-center text-center p-4">
<div>
<h2 className="text-xl font-bold mb-2">Welcome to Your Messages</h2>
<p className="text-sm text-muted-foreground">Select a chat to start messaging or create a new one.</p>
</div>
</div>
)}
</main>
</div>
);
}
5 changes: 5 additions & 0 deletions client/app/(landing-pages)/chats/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ChatUserList from './@chatList/page';

export default function ChatsPage() {
return <ChatUserList />;
}
2 changes: 1 addition & 1 deletion client/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { usePathname } from "next/navigation";
const Footer = () => {
const path = usePathname();

if (path.includes("signup") || path.includes("signin") || path.includes("admin") || path.includes("doctor")) {
if (path.includes("signup") || path.includes("signin") || path.includes("admin") || path.includes("doctor") || path.includes("chats")) {
return null;
}
return (
Expand Down
50 changes: 50 additions & 0 deletions client/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client"

import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"

import { cn } from "@/lib/utils"

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className
)}
{...props}
/>
))
Avatar.displayName = AvatarPrimitive.Root.displayName

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className
)}
{...props}
/>
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName

export { Avatar, AvatarImage, AvatarFallback }
2 changes: 1 addition & 1 deletion client/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const DoctorsSidebarLinks: NavLinkType[] = [
export const NavLinks: NavLinkType[] = [
{ href: "/", label: "Home" },
{ href: "/clinicians", label: "Clinicians" },
{ href: "/products", label: "Products" },
{ href: "/chats", label: "Chats" },
{ href: "/services", label: "Services" },
{ href: "/about", label: "About" },
];
Expand Down
27 changes: 27 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
Expand Down
1 change: 1 addition & 0 deletions client/public/assets/icons/emoji/✏️.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion client/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
@layer utilities {
/* ===== UTILITIES */
.sidebar {
@apply remove-scrollbar w-full max-w-72 flex-col overflow-auto bg-black-800 px-7 py-10;
@apply remove-scrollbar w-full max-w-72 flex-col overflow-auto px-7 py-10;
}

.left-sidebar {
Expand Down

0 comments on commit c91a00d

Please sign in to comment.