Skip to content

Commit

Permalink
refactor: Livechat Header -> ts (#30255)
Browse files Browse the repository at this point in the history
Co-authored-by: Aleksander Nicacio da Silva <[email protected]>
  • Loading branch information
2 people authored and debdutdeb committed Oct 26, 2023
1 parent ff4cdab commit 35574aa
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 57 deletions.
21 changes: 20 additions & 1 deletion packages/livechat/src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,26 @@ type AppState = {
poppedOut: boolean;
};

// eslint-disable-next-line react/prefer-stateless-function
export type ScreenPropsType = {
notificationsEnabled: boolean;
minimized: boolean;
expanded: boolean;
windowed: boolean;
sound: unknown;
alerts: unknown;
modal: unknown;
nameDefault: string;
emailDefault: string;
departmentDefault: string;
onEnableNotifications: () => unknown;
onDisableNotifications: () => unknown;
onMinimize: () => unknown;
onRestore: () => unknown;
onOpenWindow: () => unknown;
onDismissAlert: () => unknown;
dismissNotification: () => void;
};

export class App extends Component<AppProps, AppState> {
state = {
initialized: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,67 @@
import type { ComponentChildren, Ref } from 'preact';
import { toChildArray } from 'preact';
import type { JSXInternal } from 'preact/src/jsx';

import { createClassName } from '../../helpers/createClassName';
import styles from './styles.scss';

export const Header = ({ children, theme: { color: backgroundColor, fontColor: color } = {}, className, post, large, style, ...props }) => (
type HeaderProps = {
children?: ComponentChildren;
theme?: {
color?: string;
fontColor?: string;
};
className?: string;
post?: ComponentChildren;
large?: boolean;
style?: JSXInternal.CSSProperties;
ref?: Ref<HTMLElement>;
onClick?: JSXInternal.DOMAttributes<HTMLElement>['onClick'];
};

type HeaderComponentProps = {
children?: ComponentChildren;
className?: string;
};

export const Header = ({
children,
theme: { color: backgroundColor, fontColor: color } = {},
className,
post,
large,
style,
...props
}: HeaderProps) => (
<header
className={createClassName(styles, 'header', { large }, [className])}
style={style || backgroundColor || color ? { ...(style || {}), backgroundColor, color } : null}
style={style || backgroundColor || color ? { ...(style || {}), backgroundColor, color } : undefined}
{...props}
>
{children}
{post}
</header>
);

export const Picture = ({ children, className = undefined, ...props }) => (
export const Picture = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div className={createClassName(styles, 'header__picture', {}, [className])} {...props}>
{children}
</div>
);

export const Content = ({ children, className = undefined, ...props }) => (
export const Content = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div className={createClassName(styles, 'header__content', {}, [className])} {...props}>
{children}
</div>
);

export const Title = ({ children, className = undefined, ...props }) => (
export const Title = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div className={createClassName(styles, 'header__title', {}, [className])} {...props}>
{children}
</div>
);

export const SubTitle = ({ children, className = undefined, ...props }) => (
export const SubTitle = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div
className={createClassName(
styles,
Expand All @@ -48,25 +77,25 @@ export const SubTitle = ({ children, className = undefined, ...props }) => (
</div>
);

export const Actions = ({ children, className = undefined, ...props }) => (
export const Actions = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<nav className={createClassName(styles, 'header__actions', {}, [className])} {...props}>
{children}
</nav>
);

export const Action = ({ children, className = undefined, ...props }) => (
export const Action = ({ children, className = undefined, ...props }: HeaderComponentProps & { onClick?: () => void }) => (
<button className={createClassName(styles, 'header__action', {}, [className])} {...props}>
{children}
</button>
);

export const Post = ({ children, className = undefined, ...props }) => (
export const Post = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div className={createClassName(styles, 'header__post', {}, [className])} {...props}>
{children}
</div>
);

export const CustomField = ({ children, className = undefined, ...props }) => (
export const CustomField = ({ children, className = undefined, ...props }: HeaderComponentProps) => (
<div className={createClassName(styles, 'header__custom-field', {}, [className])} {...props}>
{children}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Component } from 'preact';
import { withTranslation } from 'react-i18next';
import type { ComponentChildren } from 'preact';
import { useRef } from 'preact/hooks';
import { useTranslation, withTranslation } from 'react-i18next';

import type { Agent } from '../../definitions/agents';
import MinimizeIcon from '../../icons/arrowDown.svg';
import RestoreIcon from '../../icons/arrowUp.svg';
import NotificationsEnabledIcon from '../../icons/bell.svg';
Expand All @@ -11,70 +13,84 @@ import { Avatar } from '../Avatar';
import Header from '../Header';
import Tooltip from '../Tooltip';

class ScreenHeader extends Component {
largeHeader = () => {
const { agent } = this.props;
return !!(agent && agent.email && agent.phone);
type screenHeaderProps = {
alerts: { id: string; children: ComponentChildren; [key: string]: unknown }[];
agent: Agent;
notificationsEnabled: boolean;
minimized: boolean;
expanded: boolean;
windowed: boolean;
onDismissAlert?: (id?: string) => void;
onEnableNotifications: () => unknown;
onDisableNotifications: () => unknown;
onMinimize: () => unknown;
onRestore: () => unknown;
onOpenWindow: () => unknown;
queueInfo: {
spot: number;
};
title: string;
};

headerTitle = (t) => {
const { agent, queueInfo, title } = this.props;
if (agent && agent.name) {
const ScreenHeader = ({
alerts,
agent,
notificationsEnabled,
minimized,
expanded,
windowed,
onDismissAlert,
onEnableNotifications,
onDisableNotifications,
onMinimize,
onRestore,
onOpenWindow,
queueInfo,
title,
}: screenHeaderProps) => {
const { t } = useTranslation();
const headerRef = useRef<HTMLElement>(null);

const largeHeader = () => {
return !!(agent?.email && agent.phone);
};

const headerTitle = () => {
if (agent?.name) {
return agent.name;
}

if (queueInfo && queueInfo.spot && queueInfo.spot > 0) {
if (queueInfo?.spot && queueInfo.spot > 0) {
return t('waiting_queue');
}

return title;
};

render = ({
alerts,
agent,
notificationsEnabled,
minimized,
expanded,
windowed,
onDismissAlert,
onEnableNotifications,
onDisableNotifications,
onMinimize,
onRestore,
onOpenWindow,
t,
}) => (
return (
<Header
ref={this.handleRef}
ref={headerRef}
post={
<Header.Post>
{alerts &&
alerts.map((alert) => (
<Alert {...alert} onDismiss={onDismissAlert}>
{alert.children}
</Alert>
))}
{alerts?.map((alert) => (
<Alert {...alert} onDismiss={onDismissAlert}>
{alert.children}
</Alert>
))}
</Header.Post>
}
large={this.largeHeader()}
large={largeHeader()}
>
{agent && agent.avatar && (
{agent?.avatar && (
<Header.Picture>
<Avatar
src={agent.avatar.src}
description={agent.avatar.description}
status={agent.status}
large={this.largeHeader()}
statusBorder
/>
<Avatar src={agent.avatar.src} description={agent.avatar.description} status={agent.status} large={largeHeader()} />
</Header.Picture>
)}

<Header.Content>
<Header.Title>{this.headerTitle(t)}</Header.Title>
{agent && agent.email && <Header.SubTitle>{agent.email}</Header.SubTitle>}
{agent && agent.phone && <Header.CustomField>{agent.phone}</Header.CustomField>}
<Header.Title>{headerTitle()}</Header.Title>
{agent?.email && <Header.SubTitle>{agent.email}</Header.SubTitle>}
{agent?.phone && <Header.CustomField>{agent.phone}</Header.CustomField>}
</Header.Content>
<Tooltip.Container>
<Header.Actions>
Expand Down Expand Up @@ -108,6 +124,6 @@ class ScreenHeader extends Component {
</Tooltip.Container>
</Header>
);
}
};

export default withTranslation()(ScreenHeader);
2 changes: 1 addition & 1 deletion packages/livechat/src/components/Tooltip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class TooltipContainer extends Component {
}
}

export const TooltipTrigger = ({ children, content, placement }) => (
export const TooltipTrigger = ({ children, content, placement = '' }) => (
<TooltipContext.Consumer>
{({ showTooltip, hideTooltip }) =>
toChildArray(children).map((child, index) =>
Expand Down
13 changes: 13 additions & 0 deletions packages/livechat/src/definitions/agents.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// TODO: Fully type agents in livechat
export type Agent = {
name?: string;
status?: string;
email?: string;
phone?: string;
username: string;
avatar?: {
description: string;
src: string;
};
[key: string]: unknown;
};

0 comments on commit 35574aa

Please sign in to comment.