diff --git a/frontend/app/ThemeContext.tsx b/frontend/app/ThemeContext.tsx new file mode 100644 index 000000000..51e340231 --- /dev/null +++ b/frontend/app/ThemeContext.tsx @@ -0,0 +1,64 @@ +import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; + +type ThemeType = 'light' | 'dark'; + +interface ThemeContextType { + theme: ThemeType; + toggleTheme: () => void; +} + +const ThemeContext = createContext(undefined); + +export const ThemeProvider: React.FC<{ children: ReactNode }> = ({ children }) => { + const getInitialTheme = (): ThemeType => { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme && (savedTheme === 'light' || savedTheme === 'dark')) { + return savedTheme; + } + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + }; + + const [theme, setTheme] = useState(getInitialTheme); + + useEffect(() => { + if (theme === 'dark') { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + + localStorage.setItem('theme', theme); + }, [theme]); + + useEffect(() => { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + + const handleChange = (e: MediaQueryListEvent) => { + // Only apply system preference if user hasn't manually set a preference + if (!localStorage.getItem('theme')) { + setTheme(e.matches ? 'dark' : 'light'); + } + }; + + mediaQuery.addEventListener('change', handleChange); + return () => mediaQuery.removeEventListener('change', handleChange); + }, []); + + const toggleTheme = () => { + setTheme(prevTheme => (prevTheme === 'dark' ? 'light' : 'dark')); + }; + + return ( + + {children} + + ); +}; + +export const useTheme = (): ThemeContextType => { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +}; diff --git a/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx index dd2de2cf0..63b2521b2 100644 --- a/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx +++ b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx @@ -44,16 +44,6 @@ function AddCardSelectionModal(props: Props) { className="addCard" width={isSaas ? 900 : undefined} > - {isSaas ? ( - <> - - - -
- {t('or')} -
- - ) : null}
{uxtestingStore.isUxt() ? ( diff --git a/frontend/app/components/Session_/EventsBlock/event.module.css b/frontend/app/components/Session_/EventsBlock/event.module.css index 5b5cec4a5..f6685d02b 100644 --- a/frontend/app/components/Session_/EventsBlock/event.module.css +++ b/frontend/app/components/Session_/EventsBlock/event.module.css @@ -13,7 +13,7 @@ .event { position: relative; - background: #f6f6f6; + background: $gray-lightest; /* border-radius: 3px; */ user-select: none; transition: all 0.2s; @@ -147,5 +147,5 @@ } .lastInGroup { - background: white; + background: $white; } diff --git a/frontend/app/components/Session_/playerBlockHeader.module.css b/frontend/app/components/Session_/playerBlockHeader.module.css index 29c6e1648..96a8cecad 100644 --- a/frontend/app/components/Session_/playerBlockHeader.module.css +++ b/frontend/app/components/Session_/playerBlockHeader.module.css @@ -3,7 +3,7 @@ border-bottom: solid thin $gray-light; padding-left: 15px; padding-right: 0; - background-color: white; + background-color: $white; } .divider { diff --git a/frontend/app/components/ThemeToggle/index.tsx b/frontend/app/components/ThemeToggle/index.tsx new file mode 100644 index 000000000..1b5bde18f --- /dev/null +++ b/frontend/app/components/ThemeToggle/index.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { Button } from 'antd'; +import { BulbOutlined, BulbFilled } from '@ant-design/icons'; +import { useTheme } from 'App/ThemeContext'; + +interface ThemeToggleProps { + className?: string; + style?: React.CSSProperties; + size?: 'large' | 'middle' | 'small'; +} + +const ThemeToggle: React.FC = ({ + className = '', + style = {}, + size = 'middle' +}) => { + const { theme, toggleTheme } = useTheme(); + + return ( +