Add channels and improve styles (#15)
This commit is contained in:
parent
d8d3bac048
commit
c5258f8068
|
@ -1,18 +1,235 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { ChannelData, channels } from "../helpers/channelsMock";
|
||||||
import { Theme } from "../styles/themes";
|
import { Theme } from "../styles/themes";
|
||||||
|
|
||||||
interface ChannelsProps {
|
interface ChannelsProps {
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
|
icon: string;
|
||||||
|
name: string;
|
||||||
|
members: number;
|
||||||
|
setActiveChannel: (val: ChannelData) => void;
|
||||||
|
activeChannelId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Channels({ theme }: ChannelsProps) {
|
export function Channels({
|
||||||
return <ChannelsWrapper theme={theme}>Channels</ChannelsWrapper>;
|
theme,
|
||||||
|
icon,
|
||||||
|
name,
|
||||||
|
members,
|
||||||
|
setActiveChannel,
|
||||||
|
activeChannelId,
|
||||||
|
}: ChannelsProps) {
|
||||||
|
return (
|
||||||
|
<ChannelsWrapper theme={theme}>
|
||||||
|
<Community>
|
||||||
|
<CommunityLogo src={icon} alt={`${name} logo`} />
|
||||||
|
<CommunityInfo>
|
||||||
|
<CommunityName theme={theme}>{name}</CommunityName>
|
||||||
|
<MembersAmount theme={theme}>{members} members</MembersAmount>
|
||||||
|
</CommunityInfo>
|
||||||
|
</Community>
|
||||||
|
<ChannelList>
|
||||||
|
{channels.map((channel) => (
|
||||||
|
<Channel
|
||||||
|
key={channel.id}
|
||||||
|
channel={channel}
|
||||||
|
theme={theme}
|
||||||
|
isActive={channel.id === activeChannelId}
|
||||||
|
onClick={() => {
|
||||||
|
setActiveChannel(channel);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ChannelList>
|
||||||
|
</ChannelsWrapper>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChannelsWrapper = styled.div<ChannelsProps>`
|
interface ChannelProps {
|
||||||
width: 33%;
|
theme: Theme;
|
||||||
|
channel: ChannelData;
|
||||||
|
isActive: boolean;
|
||||||
|
activeView?: boolean;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Channel({
|
||||||
|
theme,
|
||||||
|
channel,
|
||||||
|
isActive,
|
||||||
|
activeView,
|
||||||
|
onClick,
|
||||||
|
}: ChannelProps) {
|
||||||
|
return (
|
||||||
|
<ChannelWrapper
|
||||||
|
className={isActive && !activeView ? "active" : ""}
|
||||||
|
theme={theme}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<ChannelInfo>
|
||||||
|
<ChannelLogo
|
||||||
|
style={{
|
||||||
|
backgroundImage: channel.icon ? `url(${channel.icon}` : "",
|
||||||
|
}}
|
||||||
|
className={activeView ? "active" : ""}
|
||||||
|
theme={theme}
|
||||||
|
>
|
||||||
|
{!channel.icon && channel.name.slice(0, 1).toUpperCase()}
|
||||||
|
</ChannelLogo>
|
||||||
|
<ChannelTextInfo>
|
||||||
|
<ChannelName
|
||||||
|
theme={theme}
|
||||||
|
className={
|
||||||
|
isActive ? "active" : channel.notifications ? "notified" : ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
# {channel.name}
|
||||||
|
</ChannelName>
|
||||||
|
{activeView && (
|
||||||
|
<MembersAmount theme={theme}>
|
||||||
|
{" "}
|
||||||
|
{channel.members} members
|
||||||
|
</MembersAmount>
|
||||||
|
)}
|
||||||
|
</ChannelTextInfo>
|
||||||
|
</ChannelInfo>
|
||||||
|
{channel.notifications && !activeView && (
|
||||||
|
<NotificationBagde theme={theme}>
|
||||||
|
{channel.notifications}
|
||||||
|
</NotificationBagde>
|
||||||
|
)}
|
||||||
|
</ChannelWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
interface ThemeProps {
|
||||||
|
theme: Theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChannelsWrapper = styled.div<ThemeProps>`
|
||||||
|
width: 21%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: ${({ theme }) => theme.sectionBackgroundColor};
|
background-color: ${({ theme }) => theme.sectionBackgroundColor};
|
||||||
|
padding: 10px 0.6%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Community = styled.div`
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CommunityLogo = styled.img`
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CommunityInfo = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-left: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CommunityName = styled.h1<ThemeProps>`
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: ${({ theme }) => theme.textPrimaryColor};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MembersAmount = styled.p<ThemeProps>`
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
letter-spacing: 0.1px;
|
||||||
|
color: ${({ theme }) => theme.textSecondaryColor};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelList = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelWrapper = styled.div<ThemeProps>`
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: ${({ theme }) => theme.activeChannelBackground};
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelInfo = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelTextInfo = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelLogo = styled.div<ThemeProps>`
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
background-color: ${({ theme }) => theme.iconColor};
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
color: ${({ theme }) => theme.iconTextColor};
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChannelName = styled.p<ThemeProps>`
|
||||||
|
color: ${({ theme }) => theme.textPrimaryColor};
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 22px;
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
&.active,
|
||||||
|
&.notified {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.muted {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.notified {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const NotificationBagde = styled.div<ThemeProps>`
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
background-color: ${({ theme }) => theme.notificationColor};
|
||||||
|
color: ${({ theme }) => theme.bodyBackgroundColor};
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { ChannelData, channels } from "../helpers/channelsMock";
|
||||||
import { Theme } from "../styles/themes";
|
import { Theme } from "../styles/themes";
|
||||||
|
|
||||||
import { Channels } from "./Channels";
|
import { Channels } from "./Channels";
|
||||||
|
@ -9,16 +10,27 @@ import { Members } from "./Members";
|
||||||
|
|
||||||
interface ChatProps {
|
interface ChatProps {
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
channels?: boolean;
|
channelsON?: boolean;
|
||||||
members?: boolean;
|
membersON?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Chat({ theme, channels, members }: ChatProps) {
|
export function Chat({ theme, channelsON, membersON }: ChatProps) {
|
||||||
|
const [activeChannel, setActiveChannel] = useState<ChannelData>(channels[0]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatWrapper>
|
<ChatWrapper>
|
||||||
{channels && <Channels theme={theme} />}
|
{channelsON && (
|
||||||
<ChatBody />
|
<Channels
|
||||||
{members && <Members />}
|
theme={theme}
|
||||||
|
icon={"https://www.cryptokitties.co/icons/logo.svg"}
|
||||||
|
name={"CryptoKitties"}
|
||||||
|
members={186}
|
||||||
|
setActiveChannel={setActiveChannel}
|
||||||
|
activeChannelId={activeChannel.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<ChatBody theme={theme} channel={activeChannel} />
|
||||||
|
{membersON && <Members theme={theme} />}
|
||||||
</ChatWrapper>
|
</ChatWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { ChannelData } from "../../helpers/channelsMock";
|
||||||
|
import { Theme } from "../../styles/themes";
|
||||||
|
import { Channel } from "../Channels";
|
||||||
import { ChatMessage } from "../models/ChatMessage";
|
import { ChatMessage } from "../models/ChatMessage";
|
||||||
|
|
||||||
import { ChatInput } from "./ChatInput";
|
import { ChatInput } from "./ChatInput";
|
||||||
import { ChatMessages } from "./ChatMessages";
|
import { ChatMessages } from "./ChatMessages";
|
||||||
|
|
||||||
export function ChatBody() {
|
interface ChatBodyProps {
|
||||||
|
theme: Theme;
|
||||||
|
channel: ChannelData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ChatBody({ theme, channel }: ChatBodyProps) {
|
||||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||||
|
|
||||||
const addMessage = useCallback(
|
const addMessage = useCallback(
|
||||||
|
@ -20,16 +28,32 @@ export function ChatBody() {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatBodyWrapper>
|
<ChatBodyWrapper theme={theme}>
|
||||||
<ChatMessages messages={messages} />
|
<ChannelWrapper>
|
||||||
<ChatInput addMessage={addMessage} />
|
<Channel
|
||||||
|
channel={channel}
|
||||||
|
theme={theme}
|
||||||
|
isActive={true}
|
||||||
|
activeView={true}
|
||||||
|
/>
|
||||||
|
</ChannelWrapper>
|
||||||
|
<ChatMessages messages={messages} theme={theme} />
|
||||||
|
<ChatInput theme={theme} addMessage={addMessage} />
|
||||||
</ChatBodyWrapper>
|
</ChatBodyWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
interface ThemeProps {
|
||||||
|
theme: Theme;
|
||||||
|
}
|
||||||
|
|
||||||
const ChatBodyWrapper = styled.div`
|
const ChatBodyWrapper = styled.div<ThemeProps>`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 50%;
|
|
||||||
background: ${({ theme }) => theme.bodyBackgroundColor};
|
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const ChannelWrapper = styled.div`
|
||||||
|
padding-left: 8px;
|
||||||
|
`;
|
||||||
|
|
|
@ -1,41 +1,56 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { Theme } from "../../styles/themes";
|
||||||
|
|
||||||
type ChatInputProps = {
|
type ChatInputProps = {
|
||||||
|
theme: Theme;
|
||||||
addMessage: (message: string) => void;
|
addMessage: (message: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ChatInput({ addMessage }: ChatInputProps) {
|
export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
const [content, setContent] = useState("");
|
const [content, setContent] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<InputWrapper>
|
||||||
placeholder={"Message"}
|
<Input
|
||||||
value={content}
|
theme={theme}
|
||||||
onChange={(e) => setContent(e.target.value)}
|
placeholder={"Message"}
|
||||||
onKeyPress={(e) => {
|
value={content}
|
||||||
if (e.key == "Enter") {
|
onChange={(e) => setContent(e.target.value)}
|
||||||
addMessage(content);
|
onKeyPress={(e) => {
|
||||||
setContent("");
|
if (e.key == "Enter") {
|
||||||
}
|
addMessage(content);
|
||||||
}}
|
setContent("");
|
||||||
/>
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</InputWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input = styled.input`
|
interface ThemeProps {
|
||||||
|
theme: Theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 8px 6px 10px;
|
||||||
|
`;
|
||||||
|
const Input = styled.input<ThemeProps>`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: 8px;
|
margin-left: 10px;
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background: #eef2f5;
|
background: ${({ theme }) => theme.inputColor};
|
||||||
border-radius: 36px 16px 4px 36px;
|
border-radius: 36px 16px 4px 36px;
|
||||||
border: 0px;
|
border: 1px solid ${({ theme }) => theme.inputColor};
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid grey;
|
outline: none;
|
||||||
|
caret-color: ${({ theme }) => theme.notificationColor};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { Theme } from "../../styles/themes";
|
||||||
import { ChatMessage } from "../models/ChatMessage";
|
import { ChatMessage } from "../models/ChatMessage";
|
||||||
|
|
||||||
type ChatMessagesProps = {
|
type ChatMessagesProps = {
|
||||||
messages: ChatMessage[];
|
messages: ChatMessage[];
|
||||||
|
theme: Theme;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ChatMessages({ messages }: ChatMessagesProps) {
|
export function ChatMessages({ messages, theme }: ChatMessagesProps) {
|
||||||
const ref = useRef<HTMLHeadingElement>(null);
|
const ref = useRef<HTMLHeadingElement>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ref && ref.current) {
|
if (ref && ref.current) {
|
||||||
|
@ -19,15 +21,15 @@ export function ChatMessages({ messages }: ChatMessagesProps) {
|
||||||
<MessagesWrapper ref={ref}>
|
<MessagesWrapper ref={ref}>
|
||||||
{messages.map((message) => (
|
{messages.map((message) => (
|
||||||
<MessageWrapper key={message.date.toDateString()}>
|
<MessageWrapper key={message.date.toDateString()}>
|
||||||
<IconWrapper>
|
<Icon />
|
||||||
<Icon />
|
|
||||||
</IconWrapper>
|
|
||||||
<ContentWrapper>
|
<ContentWrapper>
|
||||||
<MessageHeaderWrapper>
|
<MessageHeaderWrapper>
|
||||||
<UserNameWrapper>{message.sender}</UserNameWrapper>
|
<UserNameWrapper theme={theme}>{message.sender}</UserNameWrapper>
|
||||||
<TimeWrapper>{message.date.toLocaleTimeString()}</TimeWrapper>
|
<TimeWrapper theme={theme}>
|
||||||
|
{message.date.toLocaleTimeString()}
|
||||||
|
</TimeWrapper>
|
||||||
</MessageHeaderWrapper>
|
</MessageHeaderWrapper>
|
||||||
<MessageText>{message.content}</MessageText>
|
<MessageText theme={theme}>{message.content}</MessageText>
|
||||||
</ContentWrapper>
|
</ContentWrapper>
|
||||||
</MessageWrapper>
|
</MessageWrapper>
|
||||||
))}
|
))}
|
||||||
|
@ -35,64 +37,59 @@ export function ChatMessages({ messages }: ChatMessagesProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageText = styled.div`
|
interface ThemeProps {
|
||||||
overflow-wrap: anywhere;
|
theme: Theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessagesWrapper = styled.div`
|
||||||
|
height: calc(100% - 44px);
|
||||||
|
overflow: auto;
|
||||||
|
padding: 8px 16px 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MessageWrapper = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
|
||||||
|
|
||||||
const MessageHeaderWrapper = styled.div`
|
|
||||||
display: flex;
|
display: flex;
|
||||||
`;
|
align-items: center;
|
||||||
|
padding: 8px 0;
|
||||||
const TimeWrapper = styled.div`
|
margin-bottom: 8px;
|
||||||
font-family: Inter;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 14px;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #939ba1;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
margin-left: 4px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const UserNameWrapper = styled.div`
|
|
||||||
font-family: Inter;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 22px;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ContentWrapper = styled.div`
|
const ContentWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-left: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MessageHeaderWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Icon = styled.div`
|
const Icon = styled.div`
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: blue;
|
background-color: #bcbdff;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IconWrapper = styled.div`
|
const UserNameWrapper = styled.div<ThemeProps>`
|
||||||
margin-left: 16px;
|
font-size: 15px;
|
||||||
margin-right: 8px;
|
line-height: 22px;
|
||||||
|
color: ${({ theme }) => theme.memberNameColor};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MessageWrapper = styled.div`
|
const TimeWrapper = styled.div<ThemeProps>`
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: ${({ theme }) => theme.textSecondaryColor};
|
||||||
|
margin-left: 4px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MessageText = styled.div<ThemeProps>`
|
||||||
|
overflow-wrap: anywhere;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
color: ${({ theme }) => theme.textPrimaryColor};
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const MessagesWrapper = styled.div`
|
|
||||||
height: calc(100% - 44px);
|
|
||||||
overflow: auto;
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
export function Members() {
|
import { Theme } from "../styles/themes";
|
||||||
return <MembersWrapper></MembersWrapper>;
|
|
||||||
|
interface MembersProps {
|
||||||
|
theme: Theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MembersWrapper = styled.div`
|
export function Members({ theme }: MembersProps) {
|
||||||
width: 33%;
|
return <MembersWrapper theme={theme}>Members</MembersWrapper>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MembersWrapper = styled.div<MembersProps>`
|
||||||
|
width: 18%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: ${({ theme }) => theme.sectionBackgroundColor};
|
background-color: ${({ theme }) => theme.sectionBackgroundColor};
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -9,7 +9,7 @@ export function ReactChat() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
<Chat channels={true} members={true} theme={lightTheme} />
|
<Chat channelsON={true} membersON={true} theme={lightTheme} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
export type ChannelData = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
icon?: string;
|
||||||
|
members: number;
|
||||||
|
notifications?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const channels = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "welcome",
|
||||||
|
icon: "https://www.cryptokitties.co/icons/logo.svg",
|
||||||
|
members: 7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "general",
|
||||||
|
members: 15,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "beginners",
|
||||||
|
members: 3,
|
||||||
|
notifications: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "random",
|
||||||
|
members: 6,
|
||||||
|
},
|
||||||
|
];
|
|
@ -5,7 +5,11 @@ export type Theme = {
|
||||||
sectionBackgroundColor: string;
|
sectionBackgroundColor: string;
|
||||||
memberNameColor: string;
|
memberNameColor: string;
|
||||||
guestNameColor: string;
|
guestNameColor: string;
|
||||||
|
iconColor: string;
|
||||||
|
iconTextColor: string;
|
||||||
|
activeChannelBackground: string;
|
||||||
notificationColor: string;
|
notificationColor: string;
|
||||||
|
inputColor: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const lightTheme: Theme = {
|
export const lightTheme: Theme = {
|
||||||
|
@ -15,7 +19,11 @@ export const lightTheme: Theme = {
|
||||||
sectionBackgroundColor: "#F6F8FA",
|
sectionBackgroundColor: "#F6F8FA",
|
||||||
memberNameColor: "#4360DF",
|
memberNameColor: "#4360DF",
|
||||||
guestNameColor: "#887AF9",
|
guestNameColor: "#887AF9",
|
||||||
|
iconColor: "#D37EF4",
|
||||||
|
iconTextColor: "rgba(255, 255, 255, 0.7)",
|
||||||
|
activeChannelBackground: "#E9EDF1",
|
||||||
notificationColor: "#4360DF",
|
notificationColor: "#4360DF",
|
||||||
|
inputColor: "#EEF2F5",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const darkTheme: Theme = {
|
export const darkTheme: Theme = {
|
||||||
|
@ -25,7 +33,11 @@ export const darkTheme: Theme = {
|
||||||
sectionBackgroundColor: "#252525",
|
sectionBackgroundColor: "#252525",
|
||||||
memberNameColor: "#88B0FF",
|
memberNameColor: "#88B0FF",
|
||||||
guestNameColor: "#887AF9",
|
guestNameColor: "#887AF9",
|
||||||
|
iconColor: "#D37EF4",
|
||||||
|
iconTextColor: "rgba(0, 0, 0, 0.7)",
|
||||||
|
activeChannelBackground: "#2C2C2C",
|
||||||
notificationColor: "#887AF9",
|
notificationColor: "#887AF9",
|
||||||
|
inputColor: "#373737",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default { lightTheme, darkTheme };
|
export default { lightTheme, darkTheme };
|
||||||
|
|
Loading…
Reference in New Issue