Skip to content

Commit

Permalink
feat: adds theme switch to DevSiteHeader
Browse files Browse the repository at this point in the history
  • Loading branch information
thisislawatts committed Dec 16, 2021
1 parent 79b1e3c commit 76ed805
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 70 deletions.
127 changes: 81 additions & 46 deletions src/components/DevSiteHeader/DevSiteHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,96 @@
import { SITE, VERSION, DEV_SITE_ROLE } from 'src/config/config'
import Text from 'src/components/Text'
import theme from 'src/themes/styled.theme'
import { UserRole } from 'src/models'
import { Flex, Box } from 'rebass/styled-components'
import Select from 'react-select'
import { observer } from 'mobx-react-lite'
import { useCommonStores } from 'src/index'

/**
* A simple header component that reminds developers that they are working on a dev
* version of the platform, and provide the option to toggle between different dev sites
*/
const DevSiteHeader = () => (
<>
{devSites.find(s => s.value === SITE) && (
<Flex
data-cy="devSiteHeader"
bg={theme.colors.red2}
width={1}
py={1}
px={1}
alignItems="center"
style={{ zIndex: 3001 }}
>
<Text color={'white'} medium txtcenter flex="1">
This is a dev version of the platform (v{VERSION})
</Text>
<Flex data-cy="devSiteRoleSelectContainer" alignItems="center" ml={2}>
<Text color={'white'} medium mr="1" title={SITE}>
View as:
const DevSiteHeader = observer(() => {
const { themeStore } = useCommonStores().stores
const theme = themeStore.currentTheme.styles
return (
<>
{showDevSiteHeader() && (
<Flex
data-cy="devSiteHeader"
bg={theme.colors.red2}
width={1}
py={1}
px={1}
alignItems="center"
style={{ zIndex: 3001 }}
>
<Text color={'white'} medium txtcenter flex="1">
This is a dev version of the platform (v{VERSION})
</Text>
<Box width="150px" mr={3}>
<Select
options={siteRoles}
placeholder="Role"
defaultValue={
siteRoles.find(s => s.value === DEV_SITE_ROLE) || siteRoles[0]
}
onChange={(s: any) => setSiteRole(s.value)}
/>
</Box>
<Flex data-cy="devSiteRoleSelectContainer" alignItems="center" ml={2}>
<Text color={'white'} medium mr="1" title={SITE}>
View as:
</Text>
<Box width="150px" mr={3}>
<Select
options={siteRoles}
placeholder="Role"
defaultValue={
siteRoles.find(s => s.value === DEV_SITE_ROLE) || siteRoles[0]
}
onChange={(s: any) => setSiteRole(s.value)}
/>
</Box>
</Flex>
<Flex data-cy="devSiteSelectContainer" alignItems="center">
<Text color={'white'} medium mr="1" title={SITE}>
Site:
</Text>
<Box width="130px" mr={3}>
<Select
options={devSites}
placeholder="Site"
defaultValue={devSites.find(s => s.value === SITE)}
onChange={(s: any) => setSite(s.value)}
/>
</Box>
</Flex>
<Flex data-cy="devSiteSelectContainer" alignItems="center">
<Text color={'white'} medium mr="1" title={SITE}>
Theme:
</Text>
<Box width="180px">
<Select
options={availableThemes}
placeholder="Pick a theme"
defaultValue={availableThemes.find(s => s.value === SITE)}
onChange={(selectedElement: any) => {
const theme = selectedElement?.value || ''
localStorage.setItem('platformTheme', theme)
themeStore.setActiveTheme(theme)
}}
/>
</Box>
</Flex>
</Flex>
<Flex data-cy="devSiteSelectContainer" alignItems="center">
<Text color={'white'} medium mr="1" title={SITE}>
Site:
</Text>
<Box width="130px">
<Select
options={devSites}
placeholder="Site"
defaultValue={devSites.find(s => s.value === SITE)}
onChange={(s: any) => setSite(s.value)}
/>
</Box>
</Flex>
</Flex>
)}
</>
)
)}
</>
)
})

function showDevSiteHeader() {
return (
devSites.some(s => s.value === SITE) ||
window.location?.hostname === 'localhost'
)
}

const availableThemes = [
{ value: 'precious-plastic', label: 'Precious Plastic' },
{ value: 'project-kamp', label: 'Project Kamp' },
]

// we have 2 different dev sites, only show this component when on one and provide select
const devSites = [
{ value: 'localhost', label: 'Dev' },
Expand Down
15 changes: 13 additions & 2 deletions src/components/Loader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Component } from 'react'
import { Flex, Image } from 'rebass/styled-components'
import styled, { keyframes } from 'styled-components'

import PPLogo from 'src/assets/images/precious-plastic-logo-official.svg'
import Text from 'src/components/Text'
import { inject, observer } from 'mobx-react'
import type { ThemeStore } from 'src/stores/Theme/theme.store'

interface IProps {
isMobile?: boolean
Expand All @@ -24,16 +25,26 @@ const RotatingLogo = styled(Image)`
padding: 1rem;
`

@inject('themeStore')
@observer
export class Loader extends Component<IProps> {
// eslint-disable-next-line
constructor(props: any) {
super(props)
}

get injected() {
return this.props as {
themeStore: ThemeStore,
}
}

render() {
const logo = this.injected.themeStore.currentTheme.logo || null
return (
<>
<Flex flexWrap="wrap" justifyContent="center">
<RotatingLogo src={PPLogo} width={[75, 75, 100]} />
{logo && <RotatingLogo src={logo} width={[75, 75, 100]} />}
<Text txtcenter width={1}>
loading...
</Text>
Expand Down
1 change: 1 addition & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const _supportedConfigurationOptions = [
'REACT_APP_SITE_VARIANT',
'REACT_APP_LOG_LEVEL',
'REACT_APP_SUPPORTED_MODULES',
'REACT_APP_PLATFORM_THEME',
] as const;

export type ConfigurationOption = typeof _supportedConfigurationOptions[number]
6 changes: 4 additions & 2 deletions src/pages/Howto/Content/HowtoList/HowtoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const updateQueryParams = (url: string, key: string, val: string) => {
}

// First we use the @inject decorator to bind to the howtoStore state
@inject('howtoStore', 'userStore')
@inject('howtoStore', 'userStore', 'themeStore')
// Then we can use the observer component decorator to automatically tracks observables and re-renders on change
// (note 1, use ! to tell typescript that the store will exist (it's an injected prop))
// (note 2, mobx seems to behave more consistently when observables are referenced outside of render methods)
Expand Down Expand Up @@ -93,6 +93,8 @@ export class HowtoList extends React.Component<any, IState> {
referrerSource,
} = this.props.howtoStore

const theme = this.props?.themeStore?.currentTheme

return (
<>
<Flex py={26}>
Expand All @@ -107,7 +109,7 @@ export class HowtoList extends React.Component<any, IState> {
</Box>
) : (
<Heading medium bold txtcenter width={1}>
Learn & share how to recycle, build and work with plastic
{theme && theme.howtoHeading}
</Heading>
)}
</Flex>
Expand Down
26 changes: 21 additions & 5 deletions src/pages/common/Header/Menu/Logo/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Component } from 'react';
import theme from 'src/themes/styled.theme'
import { Link, Flex, Image } from 'rebass/styled-components'
import styled from 'styled-components'
import { inject, observer } from 'mobx-react'
import type { ThemeStore } from 'src/stores/Theme/theme.store'

import PPLogo from 'src/assets/images/precious-plastic-logo-official.svg'
import Text from 'src/components/Text'
import { VERSION } from 'src/config/config'

Expand All @@ -22,12 +23,27 @@ const LogoContainer = styled(Flex)`
}
`

interface InjectedProps {
themeStore: ThemeStore
}

@inject('themeStore')
@observer
export class Logo extends Component<IProps> {
// eslint-disable-next-line
constructor(props: any) {
super(props)
}

get injected() {
return this.props as InjectedProps
}

render() {
const name = this.injected.themeStore?.currentTheme.siteName
const logo = this.injected.themeStore?.currentTheme.logo
const nameAndVersion = `${name} logo v${VERSION}`

return (
<>
<LogoContainer>
Expand All @@ -44,12 +60,12 @@ export class Logo extends Component<IProps> {
}}
>
<Image
src={PPLogo}
src={logo}
width={[50, 50, 100]}
height={[50, 50, 100]}
alt={'PP Logo v' + VERSION}
title={'PP Logo v' + VERSION}
/>
alt={nameAndVersion}
title={nameAndVersion}
/>
</Flex>
<Text
className="sr-only"
Expand Down
10 changes: 4 additions & 6 deletions src/pages/common/Header/Menu/MenuDesktop.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { Component } from 'react'
import { NavLink } from 'react-router-dom'
import { getAvailablePageList } from 'src/pages/PageList'
import theme from 'src/themes/styled.theme'
import { Flex } from 'rebass/styled-components'
import styled from 'styled-components'
import MenuCurrent from 'src/assets/images/menu-current.svg'
import { AuthWrapper } from 'src/components/Auth/AuthWrapper'
import { getSupportedModules } from 'src/modules'


const MenuLink = styled(NavLink).attrs(() => ({
activeClassName: 'current',
}))`
padding: 0px ${theme.space[4]}px;
padding: 0px ${props => props.theme.space[4]}px;
color: ${'black'};
position: relative;
> div {
z-index: ${theme.zIndex.default};
z-index: ${props => props.theme.zIndex.default};
position: relative;
&:hover {
opacity: 0.7;
Expand All @@ -30,11 +28,11 @@ const MenuLink = styled(NavLink).attrs(() => ({
display: block;
position: absolute;
bottom: -6px;
background-color: ${theme.colors.yellow.base};
background-color: ${props => props.theme.colors.yellow.base};
mask-size: contain;
mask-image: url(${MenuCurrent});
mask-repeat: no-repeat;
z-index: ${theme.zIndex.level};
z-index: ${props => props.theme.zIndex.level};
left: 50%;
transform: translateX(-50%);
pointer-events: none;
Expand Down
12 changes: 4 additions & 8 deletions src/stores/Theme/theme.store.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { action, makeAutoObservable } from 'mobx'
import type { PlatformTheme } from 'src/themes/types'
import preciousPlasticTheme from 'src/themes/precious-plastic'
import projectKampTheme from 'src/themes/project-kamp'
import { getConfigirationOption } from 'src/config/config'

const themeMap = {
'precious-plastic': preciousPlasticTheme,
'project-kamp': projectKampTheme,
}

export class ThemeStore {
currentTheme: PlatformTheme = preciousPlasticTheme

themeOptions = [
{
value: 'precious-plastic',
label: 'Precious Plastic',
},
]
currentTheme: PlatformTheme = themeMap[ localStorage.getItem('platformTheme')|| getConfigirationOption('REACT_APP_PLATFORM_THEME', 'precious-plastic')];

constructor() {
makeAutoObservable(this)
Expand Down
2 changes: 1 addition & 1 deletion src/themes/project-kamp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styles from './styles'
const Theme: PlatformTheme = {
siteName: 'Project Kamp',
logo,
howtoHeading: `Learn & share how to recycle, build and work with plastic`,
howtoHeading: `Learn & share how to recycle, build and work`,
styles,
}

Expand Down

0 comments on commit 76ed805

Please sign in to comment.