-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ce540c6
commit df0afad
Showing
8 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import prisma from '@/app/libs/prismadb'; | ||
import getCurrentUser from './getCurrentUser'; | ||
|
||
const getConversationById = async (conversationId: string) => { | ||
try { | ||
const currentUser = await getCurrentUser(); | ||
|
||
if (!currentUser) return null; | ||
|
||
const conversation = await prisma.conversation.findUnique({ | ||
where: { | ||
id: conversationId, | ||
}, | ||
include: { | ||
users: { | ||
where: { | ||
id: { | ||
not: currentUser.id, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
return conversation; | ||
} catch (error: any) { | ||
return null; | ||
} | ||
}; | ||
|
||
export default getConversationById; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import prisma from '@/app/libs/prismadb'; | ||
|
||
const getMessages = async (conversationId: string) => { | ||
try { | ||
const messages = await prisma.message.findMany({ | ||
where: { | ||
conversationId, | ||
}, | ||
include: { | ||
sender: true, | ||
seen: true, | ||
}, | ||
orderBy: { | ||
createdAt: 'asc', | ||
}, | ||
}); | ||
|
||
return messages; | ||
} catch (error: any) { | ||
return []; | ||
} | ||
}; | ||
|
||
export default getMessages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
'use client'; | ||
|
||
const Body = () => { | ||
return <div className="flex-1 overflow-y-auto">Body</div>; | ||
}; | ||
export default Body; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
'use client'; | ||
|
||
import useConversation from '@/app/hooks/useConversation'; | ||
import axios from 'axios'; | ||
import { FieldValues, SubmitHandler, useForm } from 'react-hook-form'; | ||
import { HiPhoto, HiPaperAirplane } from 'react-icons/hi2'; | ||
import MessageInput from './MessageInput'; | ||
|
||
const Form = () => { | ||
const { conversationId } = useConversation(); | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
setValue, | ||
formState: { errors }, | ||
} = useForm<FieldValues>({ | ||
defaultValues: { | ||
message: '', | ||
}, | ||
}); | ||
|
||
const onSubmit: SubmitHandler<FieldValues> = (data) => { | ||
setValue('message', '', { shouldValidate: false }); | ||
axios.post(`/api/messages`, { | ||
...data, | ||
conversationId, | ||
}); | ||
}; | ||
|
||
return ( | ||
<div className="py-4 px-4 bg-white border-t flex items-center gap-2 lg:gap-4 w-full"> | ||
<HiPhoto size={30} className="text-sky-500" /> | ||
<form | ||
onSubmit={handleSubmit(onSubmit)} | ||
className="flex items-center gap-2 lg:gap-4 w-full" | ||
> | ||
<MessageInput | ||
id="message" | ||
register={register} | ||
errors={errors} | ||
required | ||
placeholder="Type a message..." | ||
/> | ||
<button | ||
type="submit" | ||
className="rounded-full p-2 bg-sky-500 cursor-pointer hover:bg-sky-600 transition" | ||
> | ||
<HiPaperAirplane size={20} className="text-white" /> | ||
</button> | ||
</form> | ||
</div> | ||
); | ||
}; | ||
export default Form; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
'use client'; | ||
|
||
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 { HiChevronLeft } from 'react-icons/hi'; | ||
import { HiEllipsisHorizontal } from 'react-icons/hi2'; | ||
|
||
interface HeaderProps { | ||
conversation: Conversation & { | ||
users: User[]; | ||
}; | ||
} | ||
|
||
const Header: React.FC<HeaderProps> = ({ conversation }) => { | ||
const otherUser = useOtherUser(conversation); | ||
|
||
const statusText = useMemo(() => { | ||
if (conversation.isGroup) { | ||
return `${conversation.users.length} members`; | ||
} | ||
|
||
return 'Active'; | ||
}, []); | ||
|
||
return ( | ||
<div className="bg-white w-full flex border-b-[1px] sm:px-4 py-3 px-4 lg:px-6 justify-between items-center shadow-sm"> | ||
<div className="flex gap-3 items-center"> | ||
<Link | ||
className="lg:hidden block text-sky-500 hover:text-sky-600 transition cursor-pointer" | ||
href="/conversations" | ||
> | ||
<HiChevronLeft size={32} /> | ||
</Link> | ||
<Avatar user={otherUser} /> | ||
<div className="flex flex-col"> | ||
<div>{conversation.name || otherUser?.name || otherUser?.email}</div> | ||
<div className="text-sm font-light text-neutral-500"> | ||
{statusText} | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<HiEllipsisHorizontal | ||
className="text-sky-500 cursor-pointer hover:text-sky-600 transition" | ||
size={32} | ||
onClick={() => {}} | ||
/> | ||
</div> | ||
); | ||
}; | ||
export default Header; |
35 changes: 35 additions & 0 deletions
35
app/conversations/[conversationId]/components/MessageInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
'use client'; | ||
|
||
import { FieldErrors, FieldValues, UseFormRegister } from 'react-hook-form'; | ||
|
||
interface MessageInputProps { | ||
id: string; | ||
placeholder?: string; | ||
type?: string; | ||
required?: boolean; | ||
register: UseFormRegister<FieldValues>; | ||
errors: FieldErrors; | ||
} | ||
|
||
const MessageInput: React.FC<MessageInputProps> = ({ | ||
id, | ||
placeholder, | ||
type, | ||
required, | ||
register, | ||
errors, | ||
}) => { | ||
return ( | ||
<div className="relative w-full"> | ||
<input | ||
id={id} | ||
type={type} | ||
autoComplete={id} | ||
{...register(id, { required })} | ||
placeholder={placeholder} | ||
className="text-black font-light py-2 px-4 bg-neutral-100 w-full rounded-full focus:outline-none" | ||
/> | ||
</div> | ||
); | ||
}; | ||
export default MessageInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import getConversationById from '@/app/actions/getConversationById'; | ||
import getMessages from '@/app/actions/getMessages'; | ||
import EmptyState from '@/app/components/EmptyState'; | ||
import Header from './components/Header'; | ||
import Body from './components/Body'; | ||
import Form from './components/Form'; | ||
|
||
interface IParams { | ||
conversationId: string; | ||
} | ||
|
||
const ConversationId = async ({ params }: { params: IParams }) => { | ||
const conversation = await getConversationById(params.conversationId); | ||
const messages = await getMessages(params.conversationId); | ||
|
||
if (!conversation) { | ||
return ( | ||
<div className="lg:pl-80 h-full"> | ||
<div className="h-full flex flex-col"> | ||
<EmptyState /> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div className="lg:pl-80 h-full"> | ||
<div className="h-full flex flex-col"> | ||
<Header conversation={conversation} /> | ||
<Body /> | ||
<Form /> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ConversationId; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters