This repository has been archived by the owner on Jul 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from OnrampLab/issue-4-conversations
Issue 4 conversations
- Loading branch information
Showing
14 changed files
with
482 additions
and
15 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,3 @@ | ||
import { ConversationsMainPage } from '@onr/conversations'; | ||
|
||
export default ConversationsMainPage; |
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
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,206 @@ | ||
import React from 'react'; | ||
import { Anchor, Image, MessageCircle, Mic, Search as SearchIcon, Settings } from 'react-feather'; | ||
import { Button, Input, Layout, Menu, Row } from 'antd'; | ||
import { LeadAvatar } from '@onr/conversations'; | ||
import format from 'date-fns/format'; | ||
import styled from 'styled-components'; | ||
import { useSelector } from 'react-redux'; | ||
|
||
const { Header } = Layout; | ||
const { TextArea } = Input; | ||
const ChatStyled = styled.div` | ||
flex: 1; | ||
overflow-y: auto; | ||
position: relative; | ||
padding: 5rem 2rem; | ||
background-color: #f9f9f9; | ||
.weakColor & { | ||
-webkit-filter: invert(100%); | ||
filter: invert(100%); | ||
} | ||
p { | ||
margin-bottom: 0; | ||
} | ||
.conversation { | ||
box-sizing: border-box; | ||
width: 100%; | ||
margin-bottom: 1rem; | ||
display: flex; | ||
} | ||
.conversation-sent { | ||
justify-content: flex-end; | ||
} | ||
.body { | ||
position: relative; | ||
padding: 0.625rem 1rem; | ||
background-color: white; | ||
border-radius: 0.8rem; | ||
min-width: 100px; | ||
} | ||
.body-sent { | ||
position: relative; | ||
background-color: #e2f8ff; | ||
float: right; | ||
order: 1; | ||
} | ||
.date { | ||
display: block; | ||
font-size: 11px; | ||
padding-top: 2px; | ||
font-weight: 600; | ||
color: ${props => props.theme.textColorSecondary}; | ||
text-align: right; | ||
} | ||
.date-Sent { | ||
text-align: right; | ||
} | ||
input { | ||
flex: 1 1 0%; | ||
box-sizing: border-box; | ||
} | ||
`; | ||
interface ChatRoomProps { | ||
conversation: any; | ||
} | ||
|
||
export const ChatRoom: React.FC<ChatRoomProps> = ({ conversation }: ChatRoomProps) => { | ||
const isMobile = useSelector((store: any) => store.wrapper.mobile); | ||
return ( | ||
<Layout className="fill-workspace rounded shadow-sm overflow-hidden"> | ||
<Header | ||
css={` | ||
display: flex; | ||
align-items: center; | ||
padding: 0.3rem 2rem; | ||
z-index: 1; | ||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.02), 0 1px 0 rgba(0, 0, 0, 0.02); | ||
height: auto; | ||
line-height: auto; | ||
`} | ||
> | ||
{isMobile && ( | ||
<Button shape="circle" size="large" onClick={() => setContacts(true)} className="mr-3"> | ||
<MessageCircle size={20} strokeWidth={1} /> | ||
</Button> | ||
)} | ||
<Row type="flex" align="middle"> | ||
<LeadAvatar name={conversation.lead.phone} /> | ||
{!isMobile && ( | ||
<span | ||
className="ml-3" | ||
css={` | ||
line-height: 1; | ||
`} | ||
> | ||
<span | ||
css={` | ||
display: block; | ||
`} | ||
> | ||
{conversation.lead.phone} | ||
</span> | ||
<small className="text-muted"> | ||
<span>Online</span> | ||
</small> | ||
</span> | ||
)} | ||
</Row> | ||
<span className="mr-auto" /> | ||
<Menu mode="horizontal" className="border-0"> | ||
<Menu.Item> | ||
<SearchIcon size={20} strokeWidth={1} /> | ||
</Menu.Item> | ||
<Menu.Item> | ||
<Settings size={20} strokeWidth={1} /> | ||
</Menu.Item> | ||
</Menu> | ||
</Header> | ||
<Layout> | ||
<Layout> | ||
<div | ||
css={` | ||
display: flex; | ||
flex: 1; | ||
flex-direction: column; | ||
height: 100%; | ||
overflow: hidden; | ||
`} | ||
> | ||
<ChatStyled> | ||
<> | ||
{conversation.messages.map((chat, index) => ( | ||
<div | ||
key={index} | ||
className={`conversation | ||
${chat.type === 'sent' ? 'conversation-sent' : 'conversation-received'} | ||
`} | ||
> | ||
<div | ||
className={` | ||
body shadow-sm | ||
${ | ||
chat.type === 'sent' | ||
? 'body-sent' | ||
: 'body-received text-body' | ||
} | ||
`} | ||
> | ||
<p color="inherit">{chat.content}</p> | ||
<p | ||
variant="caption" | ||
className={` | ||
date | ||
${chat.type === 'sent' ? 'date-sent' : 'date-received'} | ||
`} | ||
> | ||
{format(chat.created_at, 'hh:mm')} | ||
</p> | ||
</div> | ||
</div> | ||
))} | ||
</> | ||
</ChatStyled> | ||
<div | ||
className="px-3 py-2" | ||
css={` | ||
background: #f9f9f9; | ||
`} | ||
> | ||
<div | ||
css={` | ||
display: flex; | ||
align-items: center; | ||
`} | ||
> | ||
<Menu | ||
mode="horizontal" | ||
className="border-bottom-0 bg-transparent" | ||
> | ||
<Menu.Item key="read"> | ||
<a href="javascript:;"> | ||
<Image size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
<Menu.Item key="favorite"> | ||
<a href="javascript:;"> | ||
<Anchor size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
<Menu.Item key="star"> | ||
<a href="javascript:;"> | ||
<Mic size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
</Menu> | ||
|
||
<TextArea placeholder="Type a message" autosize /> | ||
</div> | ||
</div> | ||
</div> | ||
</Layout> | ||
</Layout> | ||
</Layout> | ||
); | ||
}; |
107 changes: 107 additions & 0 deletions
107
src/modules/conversations/components/ConversationsSidebar.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,107 @@ | ||
import React, { useState } from 'react'; | ||
import { Drawer, Layout, List, Menu } from 'antd'; | ||
import { useSelector } from 'react-redux'; | ||
import { CheckCircle, Heart, RefreshCcw, Star } from 'react-feather'; | ||
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; | ||
import { LeadAvatar } from '@onr/conversations'; | ||
|
||
const { Sider } = Layout; | ||
|
||
interface ConversationsSidebarProps { | ||
conversationsData: any; | ||
onConversationSelected: any; | ||
} | ||
|
||
export const ConversationsSidebar: React.FC<ConversationsSidebarProps> = ({ | ||
conversationsData, | ||
onConversationSelected, | ||
}: ConversationsSidebarProps) => { | ||
const isMobile = useSelector((store: any) => store.wrapper.mobile); | ||
const [messages, setMessages] = useState(false); | ||
const [selectedIndex, setSelectedIndex] = useState(0); | ||
const changeIndex = (index: number) => { | ||
setSelectedIndex(index); | ||
onConversationSelected(index); | ||
}; | ||
const conversations = ( | ||
<div | ||
css={` | ||
display: flex; | ||
flex: 1; | ||
flex-direction: column; | ||
height: 100%; | ||
overflow: hidden; | ||
border-right: 1px solid rgba(0, 0, 0, 0.05); | ||
`} | ||
> | ||
<Menu mode="horizontal" className="border-0 m-auto"> | ||
<Menu.Item key="read"> | ||
<a href="javascript:;"> | ||
<CheckCircle size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
<Menu.Item key="favorite"> | ||
<a href="javascript:;"> | ||
<Heart size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
<Menu.Item key="star"> | ||
<a href="javascript:;"> | ||
<Star size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
<Menu.Item key="refresh"> | ||
<a href="javascript:;"> | ||
<RefreshCcw size={20} strokeWidth={1} /> | ||
</a> | ||
</Menu.Item> | ||
</Menu> | ||
<List | ||
className="scroll-y flex-1 bg-transparent px-3 py-1" | ||
dataSource={conversationsData} | ||
itemLayout="horizontal" | ||
renderItem={(item, index) => ( | ||
<List.Item | ||
onClick={changeIndex.bind(null, index)} | ||
style={{ | ||
backgroundColor: selectedIndex === index ? '#e6f7ff' : '', | ||
}} | ||
className={`${selectedIndex === index ? '' : 'border-0'} rounded border-0 p-3`} | ||
> | ||
<List.Item.Meta | ||
avatar={<LeadAvatar name={item.lead.phone} />} | ||
title={ | ||
<small | ||
css={` | ||
display: flex; | ||
width: 100%; | ||
`} | ||
> | ||
<span>{item.lead.phone}</span> | ||
<span className="mr-auto" /> | ||
<span>{item.latest_message && distanceInWordsToNow(new Date(item.latest_message.created_at))}</span> | ||
</small> | ||
} | ||
description={item.latest_message && item.latest_message.content} | ||
/> | ||
</List.Item> | ||
)} | ||
/> | ||
</div> | ||
); | ||
return ( | ||
<> | ||
{!isMobile && <Sider width={350}>{conversations}</Sider>} | ||
<Drawer | ||
closable={false} | ||
width={350} | ||
placement="left" | ||
onClose={() => setMessages(false)} | ||
visible={messages} | ||
className="chat-drawer" | ||
> | ||
{conversations} | ||
</Drawer> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.