diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..6f7c3e2c99 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "useTabs": true, + "singleQuote": true, + "semi": true, + "printWidth": 100, + "arrowParens": "avoid", + "trailingComma": "none", + "endOfLine": "auto" +} diff --git a/package-lock.json b/package-lock.json index 9b278a2f98..f2b49f66be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@feedyou-ai/feedbot-webchat-v0", - "version": "0.14.1-10", + "version": "0.14.1-12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/samples/.DS_Store b/samples/.DS_Store new file mode 100644 index 0000000000..96e86130b0 Binary files /dev/null and b/samples/.DS_Store differ diff --git a/samples/feedyou/newdesign.html b/samples/feedyou/newdesign.html new file mode 100644 index 0000000000..0546921542 --- /dev/null +++ b/samples/feedyou/newdesign.html @@ -0,0 +1,30 @@ + + + + + + Chatbot + + + + + + + + diff --git a/src/App/App.tsx b/src/App/App.tsx index 9ee0b42cd7..02c743d9d9 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -213,7 +213,7 @@ export const App = async (props: AppProps, container?: HTMLElement) => { // FEEDYOU configurable theming if (props.theme || !container) { - const theme = { mainColor: "#D83838", ...props.theme }; + const theme = { mainColor: "#0063f8", ...props.theme }; props.theme && (props.theme.enableScreenshotUpload = !!props.enableScreenshotUpload) const themeStyle = document.createElement("style"); themeStyle.type = "text/css"; diff --git a/src/App/templates/ExpandableTemplate/ExpandableTemplate.tsx b/src/App/templates/ExpandableTemplate/ExpandableTemplate.tsx index 3d7b5bf552..5d54c4e310 100644 --- a/src/App/templates/ExpandableTemplate/ExpandableTemplate.tsx +++ b/src/App/templates/ExpandableTemplate/ExpandableTemplate.tsx @@ -71,7 +71,7 @@ export class ExpandableTemplate extends React.Component { doesTemplateSupportPopupMsg = () => { const templateType = this.props.theme.template && this.props.theme.template.type - return ["expandable-knob", "sidebar"].includes(templateType) + return ["expandable-knob", "sidebar", "expandable-knob-v2", "sidebar-v2"].includes(templateType) } @@ -94,7 +94,7 @@ export class ExpandableTemplate extends React.Component { {signature && showSignature && - + } {this.doesTemplateSupportPopupMsg() && !initialized && popupMessage && ( diff --git a/src/App/templates/ExpandableTemplate/Header.tsx b/src/App/templates/ExpandableTemplate/Header.tsx index 0780a63180..9f384fdf12 100644 --- a/src/App/templates/ExpandableTemplate/Header.tsx +++ b/src/App/templates/ExpandableTemplate/Header.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { AppProps } from '../../App' +import { Theme } from '../../../themes' export type Props = { appProps: AppProps @@ -7,45 +8,197 @@ export type Props = { isCollapsed: boolean } -export const Header: React.StatelessComponent = ({ - appProps, - onClick, - isCollapsed, -}) => { - const { - theme: { mainColor }, - header: { extraHtml }, - } = appProps - - const backgroundColor = mainColor || '#e51836' - const title = getTitle(appProps, isCollapsed) - - - return ( - - ) +export type State = { + isMenuOpen: boolean; +}; + +export class Header extends React.Component { + state: State = { isMenuOpen: false }; + + render() { + const { + appProps: { + theme: { mainColor, template }, + header: { extraHtml } + }, + isCollapsed, + onClick + } = this.props; + + const handlePersistentMenuToggle = () => { + this.setState(prevState => ({ + isMenuOpen: !prevState.isMenuOpen + })); + }; + + let backgroundColor; + if (template.type !== 'expandable-knob-v2' && template.type !== 'sidebar-v2') { + backgroundColor = mainColor || '#fb584e'; + } + + const title = getTitle(this.props.appProps, isCollapsed); + + const avatar = + template.avatar || + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36' fill='none'%3E%3Cpath d='M36 18c0 9.941-8.059 18-18 18S0 27.941 0 18 8.059 0 18 0s18 8.059 18 18Z' fill='%23F7F9FB'/%3E%3Cpath d='M14.024 18.026h-.003v-.005h.004l.001.002v.001l-.002.002Zm3.978 0v-.001l.001-.002v-.002h-.006v.004l.002.001h.003Zm3.976 0h-.003l-.001-.002v-.002l.001-.001h.004v.003l-.001.002Z' fill='%23385B75'/%3E%3Cpath fillRule='evenodd' clipRule='evenodd' d='M18.718 9.023a8.912 8.912 0 0 1 5.669 2.59 8.91 8.91 0 0 1-10.583 14.12l-3.073 1.182a1.274 1.274 0 0 1-1.646-1.646l1.182-3.073a8.91 8.91 0 0 1 8.45-13.173ZM14.023 17a1.024 1.024 0 1 0 0 2.047 1.024 1.024 0 0 0 0-2.047Zm3.409.172a1.023 1.023 0 1 1 1.136 1.702 1.023 1.023 0 0 1-1.136-1.702ZM21.977 17a1.023 1.023 0 1 0 0 2.047 1.023 1.023 0 0 0 0-2.047Z' fill='%23385B75'/%3E%3C/svg%3E"; + + const startOverIcon = ( + + + + + ); + + return ( +
+
+ {template.type === 'expandable-knob-v2' || template.type === 'sidebar-v2' ? ( +
+ ) : null} +
+ {title} + {template.type === 'expandable-knob-v2' || template.type === 'sidebar-v2' ? ( + {template.supportiveTitle} + ) : null} +
+
+ + {extraHtml && ( + + )} + +
+ {(template.type === 'expandable-knob-v2' || template.type === 'sidebar-v2') && + (checkFeedbotTestMode() || template.persistentMenu.length > 0) ? ( +
+ + + + + + {this.state.isMenuOpen && ( + + )} +
+ ) : null} + { + e.preventDefault(); + onClick(); + }} + className="feedbot-minimize" + href="#" + > + {template.type === 'expandable-knob-v2' || template.type === 'sidebar-v2' ? ( + + + + + + ) : ( + '_' + )} + +
+
+ ); + } } const getTitle = (props: AppProps, isCollapsed: boolean) => { const { text, textWhenCollapsed } = props.header - + const titleWhenExpanded = text || 'Chatbot' const titleWhenCollapsed = textWhenCollapsed || titleWhenExpanded const titleToShow = isCollapsed ? titleWhenCollapsed : titleWhenExpanded - + return titleToShow -} +}; + +/** + * Triggers a specified dialog for the persistent menu item from Channel settings + * @param dialogId Dialog ID to be triggered on persistent menu item click + */ +const handleTriggerDialog = (dialogId: string) => { + window.dispatchEvent(new CustomEvent('feedbot:trigger-dialog', { detail: dialogId })); +}; + +/** + * Restart conversation via custom event + */ +const handleStartOver = () => { + window.dispatchEvent(new CustomEvent('feedbot:start-over')); +}; + +/** + * Check URL if test mode is being used (#feedbot-test-mode) + * @returns Boolean + */ +const checkFeedbotTestMode = (): boolean => { + return window.location.hash === '#feedbot-test-mode'; +}; export type HeaderProps = Props diff --git a/src/App/templates/ExpandableTemplate/Signature/Signature.tsx b/src/App/templates/ExpandableTemplate/Signature/Signature.tsx index c90ac10954..91aa70c5fe 100644 --- a/src/App/templates/ExpandableTemplate/Signature/Signature.tsx +++ b/src/App/templates/ExpandableTemplate/Signature/Signature.tsx @@ -1,6 +1,8 @@ import * as React from 'react' import { SignatureLink } from './SignatureLink' import { Theme } from '../../../../themes' +import { AppProps } from '../../../App' + import { SignatureTemplate } from './SignatureTemplate' type SignatureSchema = Theme['signature'] @@ -8,32 +10,88 @@ const FEEDYOU_LOGO_IMG_SRC = 'https://cdn.feedyou.ai/webchat/feedyou_logo_red.pn export type Props = { signature: SignatureSchema + appProps: AppProps botId: string } const getLinkQueryString = (botId: string) => `?utm_source=webchat&utm_medium=chatbot&utm_campaign=${botId}` -export const Signature: React.StatelessComponent = ({ signature, botId }) => { - const { partnerLogoUrl, partnerLinkUrl, partnerLogoStyle, mode } = signature - const attachQueryStringToUrl = (url: string) => `${url}${getLinkQueryString(botId)}` - - const enhancedFeedyouUrl = attachQueryStringToUrl('https://feedyou.ai') - const enhancedPartnerUrl = partnerLinkUrl ? attachQueryStringToUrl(partnerLinkUrl) : enhancedFeedyouUrl - - const feedyouLink = - - const partnerLink = - - if(mode === 'none') { - return null +export const Signature: React.StatelessComponent = ({ + signature, + botId, + appProps, +}) => { + const { + partnerLogoUrl, + partnerLinkUrl, + partnerLogoStyle, + mode, + partnerName, + } = signature + const { + theme: { template }, + } = appProps + + const attachQueryStringToUrl = (url: string) => + `${url}${getLinkQueryString(botId)}` + + const enhancedFeedyouUrl = attachQueryStringToUrl('https://feedyou.ai'); + const enhancedPartnerUrl = partnerLinkUrl + ? attachQueryStringToUrl(partnerLinkUrl) + : enhancedFeedyouUrl + + const feedyouLink = ( + + ); + + const partnerLink = ( + + ); + + if (mode === 'none') { + return null; + } + + /* Webchat Redesign Signature */ + if ( + template.type === 'expandable-knob-v2' || + template.type === 'sidebar-v2' + ) { + if (mode === 'both') { + return ( + + {partnerLink} &{' '} + + Feedyou + + + ); + } + if (mode === 'partner') { + return {partnerLink} + } + return ( + + + Feedyou + + + ); } if (partnerLogoUrl && mode === 'both') { @@ -45,7 +103,7 @@ export const Signature: React.StatelessComponent = ({ signature, botId }) ) } - + if (partnerLogoUrl && mode === 'partner') { return ( @@ -53,7 +111,7 @@ export const Signature: React.StatelessComponent = ({ signature, botId }) ) } - + return ( {feedyouLink} diff --git a/src/App/templates/ExpandableTemplate/Signature/SignatureLink.tsx b/src/App/templates/ExpandableTemplate/Signature/SignatureLink.tsx index c6b587f913..e163895de2 100644 --- a/src/App/templates/ExpandableTemplate/Signature/SignatureLink.tsx +++ b/src/App/templates/ExpandableTemplate/Signature/SignatureLink.tsx @@ -7,22 +7,23 @@ export type Props = { imgSrc: string className?: string customStyles?: string -} + text?: string +}; export const SignatureLink: React.StatelessComponent = ({ href, imgSrc, className, customStyles, + text, }) => { return ( - Logo + {imgSrc ? Logo : text} {className && customStyles && } ) } - export type SignatureLinkProps = Props diff --git a/src/App/templates/ExpandableTemplate/Signature/SignatureTemplate.tsx b/src/App/templates/ExpandableTemplate/Signature/SignatureTemplate.tsx index 12a439fe13..7f6329f834 100644 --- a/src/App/templates/ExpandableTemplate/Signature/SignatureTemplate.tsx +++ b/src/App/templates/ExpandableTemplate/Signature/SignatureTemplate.tsx @@ -8,10 +8,9 @@ export const SignatureTemplate: React.StatelessComponent = ({ children }) => { return (
-
with ❤️ by
+
powered by
{children}
) } - diff --git a/src/Shell.tsx b/src/Shell.tsx index 66e4a3ebab..11ce524c91 100644 --- a/src/Shell.tsx +++ b/src/Shell.tsx @@ -145,8 +145,9 @@ class ShellContainer extends React.Component implements ShellFunctions { tabIndex={0} > - - + + + } { @@ -193,8 +194,9 @@ class ShellContainer extends React.Component implements ShellFunctions { type="button" > - - + + +