Enable dark mode and fix theme

This commit is contained in:
Felix Malfait
2023-06-05 22:20:55 +02:00
parent 3ae6405f4d
commit 41fe78bc4c
17 changed files with 478 additions and 73 deletions

View File

@ -1,9 +1,13 @@
import React, { useEffect, useState } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { ThemeProvider } from '@emotion/react';
import { browserPrefersDarkMode } from '@/utils/utils';
import { RequireAuth } from './modules/auth/components/RequireAuth';
import { getUserIdFromToken } from './modules/auth/services/AuthService';
import { AppLayout } from './modules/ui/layout/AppLayout';
import { darkTheme, lightTheme } from './modules/ui/layout/styles/themes';
import { mapToUser, User } from './modules/users/interfaces/user.interface';
import { useGetCurrentUserQuery } from './modules/users/services';
import AuthCallback from './pages/auth/Callback';
@ -12,7 +16,11 @@ import { Companies } from './pages/companies/Companies';
import { Opportunities } from './pages/opportunities/Opportunities';
import { People } from './pages/people/People';
export function App() {
type AppProps = {
themeEnabled?: boolean;
};
export function App({ themeEnabled = true }: AppProps) {
const [user, setUser] = useState<User | undefined>(undefined);
const userIdFromToken = getUserIdFromToken();
@ -24,7 +32,9 @@ export function App() {
}
}, [data]);
return (
const defaultTheme = browserPrefersDarkMode() ? darkTheme : lightTheme;
const app = (
<>
{
<AppLayout user={user}>
@ -68,4 +78,14 @@ export function App() {
}
</>
);
return (
<>
{themeEnabled ? (
<ThemeProvider theme={defaultTheme}>{app}</ThemeProvider>
) : (
app
)}
</>
);
}

View File

@ -1,10 +1,8 @@
import { MemoryRouter } from 'react-router-dom';
import { ApolloProvider } from '@apollo/client';
import { ThemeProvider } from '@emotion/react';
import type { Meta, StoryObj } from '@storybook/react';
import { RecoilRoot } from 'recoil';
import { lightTheme } from '@/ui/layout/styles/themes';
import { App } from '~/App';
import { FullHeightStorybookLayout } from '~/testing/FullHeightStorybookLayout';
import { graphqlMocks } from '~/testing/graphqlMocks';
@ -22,13 +20,11 @@ type Story = StoryObj<typeof App>;
const render = () => (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ThemeProvider theme={lightTheme}>
<MemoryRouter>
<FullHeightStorybookLayout>
<App />
</FullHeightStorybookLayout>
</MemoryRouter>
</ThemeProvider>
<MemoryRouter>
<FullHeightStorybookLayout>
<App themeEnabled={false} />
</FullHeightStorybookLayout>
</MemoryRouter>
</ApolloProvider>
</RecoilRoot>
);

View File

@ -12,9 +12,6 @@ const StyledIconButton = styled.button`
border: none;
border-radius: 50%;
background: ${(props) => props.theme.text80};
color: ${(props) => props.theme.text100};
transition: color 0.1s ease-in-out, background 0.1s ease-in-out;
background: ${(props) => props.theme.blue};
@ -22,7 +19,7 @@ const StyledIconButton = styled.button`
cursor: pointer;
&:disabled {
background: ${(props) => props.theme.quadraryBackground};
background: ${(props) => props.theme.quaternaryBackground};
color: ${(props) => props.theme.text80};
cursor: default;
}

View File

@ -166,10 +166,6 @@ const StyledContainer = styled.div`
line-height: 34px;
}
& .react-datepicker__day--selected {
background-color: ${(props) => props.theme.blue};
}
& .react-datepicker__navigation--previous,
& .react-datepicker__navigation--next {
height: 34px;
@ -205,12 +201,26 @@ const StyledContainer = styled.div`
border-color: ${(props) => props.theme.text40};
}
& .react-datepicker__day--keyboard-selected {
background-color: inherit;
}
& .react-datepicker__day,
.react-datepicker__time-name {
color: ${(props) => props.theme.text80};
}
& .react-datepicker__day--selected {
background-color: ${(props) => props.theme.blue};
color: ${(props) => props.theme.text0};
}
& .react-datepicker__day--outside-month {
color: ${(props) => props.theme.text40};
}
& .react-datepicker__day--keyboard-selected {
background-color: inherit;
& .react-datepicker__day:hover {
color: ${(props) => props.theme.text40};
}
`;

View File

@ -1,10 +1,8 @@
import { ThemeProvider } from '@emotion/react';
import styled from '@emotion/styled';
import { User } from '@/users/interfaces/user.interface';
import { Navbar } from './navbar/Navbar';
import { lightTheme } from './styles/themes';
const StyledLayout = styled.div`
display: flex;
@ -31,17 +29,15 @@ type OwnProps = {
export function AppLayout({ children, user }: OwnProps) {
const userIsAuthenticated = !!user;
return (
<ThemeProvider theme={lightTheme}>
<StyledLayout>
{userIsAuthenticated ? (
<>
<Navbar user={user} workspace={user?.workspaceMember?.workspace} />
<MainContainer>{children}</MainContainer>
</>
) : (
children
)}
</StyledLayout>
</ThemeProvider>
<StyledLayout>
{userIsAuthenticated ? (
<>
<Navbar user={user} workspace={user?.workspaceMember?.workspace} />
<MainContainer>{children}</MainContainer>
</>
) : (
children
)}
</StyledLayout>
);
}

View File

@ -36,6 +36,7 @@ const StyledName = styled.div`
font-family: 'Inter';
font-weight: 500;
font-size: ${(props) => props.theme.fontSizeLarge};
color: ${(props) => props.theme.text80};
`;
function WorkspaceContainer({ workspace }: OwnProps) {

View File

@ -27,10 +27,11 @@ const commonTheme = {
const lightThemeSpecific = {
noisyBackground: `url(${LightNoise.toString()});`,
primaryBackground: '#fff',
secondaryBackground: '#fcfcfc',
tertiaryBackground: '#f5f5f5',
quadraryBackground: '#ebebeb',
quaternaryBackground: '#ebebeb',
pinkBackground: '#ffe5f4',
greenBackground: '#e6fff2',
@ -68,8 +69,8 @@ const darkThemeSpecific: typeof lightThemeSpecific = {
noisyBackground: `url(${DarkNoise.toString()});`,
primaryBackground: '#141414',
secondaryBackground: '#171717',
tertiaryBackground: '#333333',
quadraryBackground: '#444444',
tertiaryBackground: '#1B1B1B',
quaternaryBackground: '#1D1D1D',
pinkBackground: '#cc0078',
greenBackground: '#1e7e50',
@ -115,6 +116,7 @@ export const textInputStyle = (props: any) =>
border: none;
outline: none;
background-color: transparent;
color: ${props.theme.text80};
&::placeholder,
&::-webkit-input-placeholder {

View File

@ -9,3 +9,7 @@ export const humanReadableDate = (date: Date) => {
export const getLogoUrlFromDomainName = (domainName?: string): string => {
return `https://api.faviconkit.com/${domainName}/144`;
};
export const browserPrefersDarkMode = (): boolean => {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
};

View File

@ -1,11 +1,9 @@
import { MemoryRouter } from 'react-router-dom';
import { ApolloProvider } from '@apollo/client';
import { ThemeProvider } from '@emotion/react';
import { graphql } from 'msw';
import { RecoilRoot } from 'recoil';
import { GraphqlQueryCompany } from '@/companies/interfaces/company.interface';
import { lightTheme } from '@/ui/layout/styles/themes';
import { GraphqlQueryUser } from '@/users/interfaces/user.interface';
import { FullHeightStorybookLayout } from '~/testing/FullHeightStorybookLayout';
import { filterAndSortData } from '~/testing/mock-data';
@ -48,13 +46,11 @@ export function render() {
return (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ThemeProvider theme={lightTheme}>
<MemoryRouter>
<FullHeightStorybookLayout>
<Companies />
</FullHeightStorybookLayout>
</MemoryRouter>
</ThemeProvider>
<MemoryRouter>
<FullHeightStorybookLayout>
<Companies />
</FullHeightStorybookLayout>
</MemoryRouter>
</ApolloProvider>
</RecoilRoot>
);

View File

@ -1,9 +1,7 @@
import { MemoryRouter } from 'react-router-dom';
import { ApolloProvider } from '@apollo/client';
import { ThemeProvider } from '@emotion/react';
import { RecoilRoot } from 'recoil';
import { lightTheme } from '@/ui/layout/styles/themes';
import { FullHeightStorybookLayout } from '~/testing/FullHeightStorybookLayout';
import { mockedClient } from '~/testing/mockedClient';
@ -13,13 +11,11 @@ export function render() {
return (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ThemeProvider theme={lightTheme}>
<MemoryRouter>
<FullHeightStorybookLayout>
<People />
</FullHeightStorybookLayout>
</MemoryRouter>
</ThemeProvider>
<MemoryRouter>
<FullHeightStorybookLayout>
<People />
</FullHeightStorybookLayout>
</MemoryRouter>
</ApolloProvider>
</RecoilRoot>
);

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,8 @@
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { ApolloProvider } from '@apollo/client';
import { ThemeProvider } from '@emotion/react';
import { RecoilRoot } from 'recoil';
import { lightTheme } from '@/ui/layout/styles/themes';
import { ComponentStorybookLayout } from './ComponentStorybookLayout';
import { FullHeightStorybookLayout } from './FullHeightStorybookLayout';
import { mockedClient } from './mockedClient';
@ -15,11 +12,9 @@ export function getRenderWrapperForPage(children: React.ReactElement) {
return (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ThemeProvider theme={lightTheme}>
<MemoryRouter>
<FullHeightStorybookLayout>{children}</FullHeightStorybookLayout>
</MemoryRouter>
</ThemeProvider>
<MemoryRouter>
<FullHeightStorybookLayout>{children}</FullHeightStorybookLayout>
</MemoryRouter>
</ApolloProvider>
</RecoilRoot>
);
@ -31,9 +26,7 @@ export function getRenderWrapperForComponent(children: React.ReactElement) {
return (
<RecoilRoot>
<ApolloProvider client={mockedClient}>
<ThemeProvider theme={lightTheme}>
<ComponentStorybookLayout>{children}</ComponentStorybookLayout>
</ThemeProvider>
<ComponentStorybookLayout>{children}</ComponentStorybookLayout>
</ApolloProvider>
</RecoilRoot>
);