diff --git a/packages/docs/docusaurus.config.js b/packages/docs/docusaurus.config.js index 0ffbd70998..be47b36fa7 100644 --- a/packages/docs/docusaurus.config.js +++ b/packages/docs/docusaurus.config.js @@ -87,34 +87,55 @@ const config = { style: "dark", links: [ { - title: "Docs", + title: "Company", items: [ { - label: "Tutorial", - to: "/docs/introduction", + label: "About Rocket.Chat", + href: "https://www.rocket.chat/about", + }, + { + label: "Careers", + href: "https://www.rocket.chat/careers", + }, + { + label: "Contact", + href: "https://www.rocket.chat/contact", }, ], }, { - title: "Community", + title: "Platform", items: [ { - label: "Rocket.Chat", - href: "https://open.rocket.chat/", + label: "Embedded Chat", + to: "/", }, { - label: "Twitter", - href: "https://x.com/rocketchat", + label: "Rocket.Chat Server", + href: "https://www.rocket.chat/docs", }, ], }, { - title: "More", + title: "Resources", items: [ { - label: "Blogs", + label: "Blog", to: "/blog", }, + { + label: "Community", + href: "https://open.rocket.chat/", + }, + ], + }, + { + title: "Social", + items: [ + { + label: "Twitter", + href: "https://x.com/rocketchat", + }, { label: "GitHub", href: "https://github.com/RocketChat/EmbeddedChat", @@ -122,6 +143,13 @@ const config = { ], }, ], + logo: { + alt: "Rocket.Chat Logo", + src: "img/rocketchat-logo-white-v2.png", + href: "https://www.rocket.chat", + width: 160, + }, + copyright: `Copyright © ${new Date().getFullYear()} Rocket.Chat Technologies Corp.`, }, colorMode: { defaultMode: 'light', diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css index 8697856532..27ee52f539 100644 --- a/packages/docs/src/css/custom.css +++ b/packages/docs/src/css/custom.css @@ -1,30 +1,94 @@ /** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. + * Rocket.Chat Brand Identity Overrides */ -/* You can override the default Infima variables here. */ -[data-theme='light']:root { - --ifm-color-primary: #1f3e05; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; +:root { + --ifm-color-primary: #F5455C; + --ifm-color-primary-dark: #E03F54; + --ifm-color-primary-darker: #D43A4F; + --ifm-color-primary-darkest: #AF3041; + --ifm-color-primary-light: #F76A7D; + --ifm-color-primary-lighter: #F98F9D; + --ifm-color-primary-lightest: #FBB4BD; --ifm-code-font-size: 95%; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + + /* Footer Variables */ + --ifm-footer-background-color: #000000 !important; + --ifm-footer-color: #ffffff; + --ifm-footer-link-color: #BCC3CD; + --ifm-footer-link-hover-color: #ffffff; } -/* For readability concerns, you should choose a lighter palette in dark mode. */ [data-theme='dark'] { - --ifm-color-primary: #a0c680; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; + --ifm-color-primary: #F5455C; + --ifm-color-primary-dark: #E03F54; + --ifm-color-primary-darker: #D43A4F; + --ifm-color-primary-darkest: #AF3041; + --ifm-color-primary-light: #F76A7D; + --ifm-color-primary-lighter: #F98F9D; + --ifm-color-primary-lightest: #FBB4BD; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } + +/* Footer Enhancements */ +.footer.footer--dark { + background-color: #000000 !important; + padding: 4rem 2rem 2rem; +} + +.footer__title { + color: #ffffff !important; + font-weight: 700; + margin-bottom: 1.25rem; + text-transform: uppercase; + font-size: 0.85rem; + letter-spacing: 1px; +} + +.footer__link-item { + color: var(--ifm-footer-link-color) !important; + transition: all 0.2s ease-in-out; + line-height: 2; + font-size: 0.95rem; +} + +.footer__link-item:hover { + color: var(--ifm-footer-link-hover-color) !important; + text-decoration: none; +} + +.footer__copyright { + margin-top: 3rem; + padding-top: 2rem; + border-top: 1px solid #2F343D; + color: #9EA2A8; + font-size: 0.85rem; + text-align: left; +} + +.footer__logo { + margin-bottom: 1.5rem; + opacity: 0.9; + transition: opacity 0.2s ease; +} + +.footer__logo:hover { + opacity: 1; +} + +/* Responsive Grid Tweaks */ +@media (max-width: 996px) { + .footer__links { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 2rem; + } +} + +@media (max-width: 480px) { + .footer__links { + grid-template-columns: 1fr; + } +} + diff --git a/packages/docs/static/img/rocketchat-logo-white-v2.png b/packages/docs/static/img/rocketchat-logo-white-v2.png new file mode 100644 index 0000000000..c9f85c00ba Binary files /dev/null and b/packages/docs/static/img/rocketchat-logo-white-v2.png differ diff --git a/packages/docs/static/img/rocketchat-logo-white.png b/packages/docs/static/img/rocketchat-logo-white.png new file mode 100644 index 0000000000..c2c7648544 Binary files /dev/null and b/packages/docs/static/img/rocketchat-logo-white.png differ diff --git a/packages/react/src/lib/auth.js b/packages/react/src/lib/auth.js index c3ac9ca586..4304cf02cf 100644 --- a/packages/react/src/lib/auth.js +++ b/packages/react/src/lib/auth.js @@ -1,46 +1,31 @@ -async function saveTokenLocalStorage(token) { - if (typeof localStorage !== 'undefined') { - localStorage.setItem('ec_token', token); - } -} - -async function getTokenLocalStorage() { - if (typeof localStorage !== 'undefined') { - return localStorage.getItem('ec_token'); - } - return null; -} - -async function deleteTokenLocalStorage() { - if (typeof localStorage !== 'undefined') { - localStorage.removeItem('ec_token'); - } -} - -async function saveTokenSecure(token) { - this.handleSecureLogin('save', token); -} - -async function getTokenSecure() { - const response = await this.handleSecureLogin('get'); - return response?.token !== undefined ? response.token : null; -} - -async function deleteTokenSecure() { - this.handleSecureLogin('delete'); -} - -export function getTokenStorage(secure = false) { +export function getTokenStorage(secure = false, handleSecureLogin) { if (secure) { return { - saveToken: saveTokenSecure, - getToken: getTokenSecure, - deleteToken: deleteTokenSecure, + saveToken: async (token) => handleSecureLogin('save', token), + getToken: async () => { + const response = await handleSecureLogin('get'); + return response?.token !== undefined ? response.token : null; + }, + deleteToken: async () => handleSecureLogin('delete'), }; } + return { - saveToken: saveTokenLocalStorage, - getToken: getTokenLocalStorage, - deleteToken: deleteTokenLocalStorage, + async saveToken(token) { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('ec_token', token); + } + }, + async getToken() { + if (typeof localStorage !== 'undefined') { + return localStorage.getItem('ec_token'); + } + return null; + }, + async deleteToken() { + if (typeof localStorage !== 'undefined') { + localStorage.removeItem('ec_token'); + } + }, }; } diff --git a/packages/react/src/views/EmbeddedChat.js b/packages/react/src/views/EmbeddedChat.js index f3b94c7b48..4a300b8b87 100644 --- a/packages/react/src/views/EmbeddedChat.js +++ b/packages/react/src/views/EmbeddedChat.js @@ -64,7 +64,20 @@ const EmbeddedChat = (props) => { const { classNames, styleOverrides } = useComponentOverrides('EmbeddedChat'); const [fullScreen, setFullScreen] = useState(false); const [isSynced, setIsSynced] = useState(!remoteOpt); - const { getToken, saveToken, deleteToken } = getTokenStorage(secure); + const RCInstanceRef = useRef(null); + + const handleSecureLogin = useCallback((action, token) => { + if (RCInstanceRef.current) { + return RCInstanceRef.current.auth.handleSecureLogin(action, token); + } + return null; + }, []); + + const { getToken, saveToken, deleteToken } = useMemo( + () => getTokenStorage(secure, handleSecureLogin), + [secure, handleSecureLogin] + ); + const { setIsUserAuthenticated, setUsername: setAuthenticatedUsername, @@ -95,7 +108,7 @@ const EmbeddedChat = (props) => { deleteToken, saveToken, }); - + RCInstanceRef.current = newRCInstance; return newRCInstance; }, [host, roomId, getToken, deleteToken, saveToken]);