Skip to content

Commit

Permalink
White-Labelling (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinejaussoin authored Jun 20, 2023
1 parent 2e15b32 commit 9b7f255
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 10 deletions.
35 changes: 34 additions & 1 deletion .github/workflows/alpha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: 'Alpha Build'

on:
push:
branches: [v512/palette-bug]
branches: [v530/custom-colour]

jobs:
frontend:
Expand Down Expand Up @@ -104,6 +104,39 @@ jobs:
platforms: linux/amd64
push: true

documentation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Read VERSION
id: package
uses: martinbeentjes/npm-get-version-action@master
- name: Echo VERSION
run: echo ${{ steps.package.outputs.current-version }}
- name: Setup QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: all
- name: Setup BuildX
uses: docker/setup-buildx-action@v2
id: buildx
with:
install: true
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_NEW_USERNAME }}
password: ${{ secrets.DOCKER_NEW_PASSWORD }}
- name: Build and push Documentation
uses: docker/build-push-action@v4
with:
builder: ${{ steps.buildx.outputs.name }}
file: docs/Dockerfile
context: docs
tags: retrospected/docs:alpha
platforms: linux/amd64
push: true

integration:
runs-on: ubuntu-latest
needs: [frontend, backend]
Expand Down
5 changes: 5 additions & 0 deletions docs/docs/self-hosting/optionals.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ services:
FRONTEND_DEFAULT_LANGUAGE: 'en-GB' # Set the default language for new users
FRONTEND_MARKETING_ROOT: 'https://www.retrospected.com' # URL of the marketing website
FRONTEND_AI_FEEDBACK_URL: 'http://' # URL of a freeform feedback form for AI feedback
FRONTEND_PRIMARY_COLOR: # List of 14 colours representing the primary color. See documentation.
FRONTEND_SECONDARY_COLOR: # List of 14 colours representing the primary color. See documentation.
FRONTEND_HEADER_PRIMARY_COLOR: # Colour of the header. If not set, the Primary color will be used. See Documentation.
FRONTEND_HEADER_SECONDARY_COLOR: # Secondary Colour of the header. See Documentation.
FRONTEND_LOGO: # image data URL representation of the logo. See documentation.

# -- Do Not Change --
BACKEND_HOST: backend # This should be the name of the backend service
Expand Down
20 changes: 20 additions & 0 deletions docs/docs/self-hosting/quick-start/ComposeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ type ComposeViewSettings = {
smtpUser: string;
smtpPassword: string;
smtpSender: string;
primaryColours: string;
secondaryColours: string;
primaryHeaderColour: string;
secondaryHeaderColour: string;
logo: string;
};

type ComposeViewProps = {
Expand All @@ -38,6 +43,10 @@ function p(condition: boolean, key: string, value: string, number = false) {
: null;
}

function d(value: string) {
return value ? `'${value}'` : '# Not provided. Using defaults.';
}

export default function ComposeView({
settings: {
dbPassword,
Expand All @@ -61,6 +70,11 @@ export default function ComposeView({
smtpUser,
smtpPassword,
smtpSender,
primaryColours,
secondaryColours,
primaryHeaderColour,
secondaryHeaderColour,
logo,
},
}: ComposeViewProps) {
const optionals = [
Expand All @@ -86,6 +100,12 @@ services:
ports:
- '${port}:80'
restart: unless-stopped
environment:
FRONTEND_PRIMARY_COLOURS: ${d(primaryColours)}
FRONTEND_SECONDARY_COLOURS: ${d(secondaryColours)}
FRONTEND_PRIMARY_HEADER_COLOUR: ${d(primaryHeaderColour)}
FRONTEND_SECONDARY_HEADER_COLOUR: ${d(secondaryHeaderColour)}
FRONTEND_LOGO: ${d(logo)}
logging:
driver: 'json-file'
options:
Expand Down
65 changes: 65 additions & 0 deletions docs/docs/self-hosting/quick-start/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ export default function Editor() {
''
);
const [smtpSender, setSmtpSender] = usePersistedState('smtp-sender', '');
const [primaryColours, setPrimaryColours] = usePersistedState(
'primary-colours',
''
);
const [secondaryColours, setSecondaryColours] = usePersistedState(
'secondary-colours',
''
);
const [primaryHeaderColour, setPrimaryHeaderColour] = usePersistedState(
'primary-header-colour',
''
);
const [secondaryHeaderColour, setSecondaryHeaderColour] = usePersistedState(
'secondary-header-colour',
''
);
const [logo, setLogo] = usePersistedState('logo', '');

useEffect(() => {
if (isBrowser) {
Expand Down Expand Up @@ -242,6 +259,49 @@ export default function Editor() {
) : null}
</div>
</Accordion>
<Accordion title="White-Labelling & Customisation">
<p>
More documentation here:{' '}
<a href="./white-labelling">white-labelling documentation</a>.
</p>
<div className={styles.settings}>
<InputField
label="Primary Colours"
description="Comma-separated list of 14 primary colours"
placeholder="#ffebee,#ffcdd2,#ef9a9a,#e57373,#ef5350,#f44336,#e53935,#d32f2f,#c62828,#b71c1c,#ff8a80,#ff5252,#ff1744,#d50000"
value={primaryColours}
onChange={setPrimaryColours}
/>
<InputField
label="Secondary Colours"
description="Comma-separated list of 14 secondary colours"
placeholder="#ffebee,#ffcdd2,#ef9a9a,#e57373,#ef5350,#f44336,#e53935,#d32f2f,#c62828,#b71c1c,#ff8a80,#ff5252,#ff1744,#d50000"
value={secondaryColours}
onChange={setSecondaryColours}
/>
<InputField
label="Primary Header Colour"
description="The colour of the header background"
placeholder="#000000"
value={primaryHeaderColour}
onChange={setPrimaryHeaderColour}
/>
<InputField
label="Secondary Header Colour"
description="The colour of the header text"
placeholder="#ffffff"
value={secondaryHeaderColour}
onChange={setSecondaryHeaderColour}
/>
<InputField
label="Logo URL or Data URI"
description="The URL to the logo to use in the header. Or use a data URI."
placeholder="https://example.com/logo.png"
value={logo}
onChange={setLogo}
/>
</div>
</Accordion>
<h3>Your customised docker-compose file:</h3>

<ComposeView
Expand All @@ -267,6 +327,11 @@ export default function Editor() {
smtpUser,
smtpPassword,
smtpSender,
primaryColours,
secondaryColours,
primaryHeaderColour,
secondaryHeaderColour,
logo,
}}
/>
<h1>2 - Run Docker</h1>
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/self-hosting/quick-start/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styles from './Field.module.css';
export type FieldProps = {
label: string;
description?: string;
placeholder?: string;
};

type InputFieldProps = FieldProps & {
Expand Down Expand Up @@ -31,11 +32,13 @@ export function InputField({
label,
description,
number,
placeholder,
onChange,
}: InputFieldProps) {
return (
<Field label={label} description={description}>
<input
placeholder={placeholder}
className={styles.input}
value={value}
onKeyPress={number ? onlyNumbers : onlyAlpha}
Expand Down
86 changes: 86 additions & 0 deletions docs/docs/self-hosting/white-labelling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
sidebar_position: 1.2
---

# 🎨 White-Labelling

When self-hosting your own instance of Retrospected, you have the possibility of customising the colours and the logo so they are more in line with your company's branding.

:::info This is optional
White-Labelling, or customising colours and logo, is entirely optional. You can skip this section if you don't need it.
:::

As an example, we can easily re-brand Retrospected to fit with the British Red Cross colours:

![An example of White-Labelling](/img/self-hosting/white-labelling-example-2.png)

## What can I configure

You have the ability to change 4 details:

- The Primary colour (this is the colour of most components, purple by default)
- The Secondary colour (this is the colour of some secondary components, like buttons, pink by default)
- The Header colour (by default, it takes the primary colour, but you can choose something else)
- The Logo

## How can I configure it

All the following are to be set in the `docker-compose.yml` file, in the `frontend` section.

Alternatively, you can set this up using the docker-compose editor [here](quick-start).

### Configure the Primary and Secondary colours

Both the Primary and the Secondary colours are actually a palette of 14 colours.

You can see examples of this here: [https://materialui.co/colors/](https://materialui.co/colors/).

You must choose 14 colours, that are each a variation of each other, from very light to very dark.

This is an example with a red-ish colour, as seen in the Red Cross example above:

You will notice that the list of 14 colours is a list of 14 HEX RGB colours, separated by commas.

```yaml
FRONTEND_PRIMARY_COLOR: '#ffebee,#ffcdd2,#ef9a9a,#e57373,#ef5350,#f44336,#e53935,#d32f2f,#c62828,#b71c1c,#ff8a80,#ff5252,#ff1744,#d50000'
```
Do the same for the secondary colour, with 14 other colours.
Example:
```yaml
FRONTEND_SECONDARY_COLOR: '#e8f5e9,#c8e6c9,#a5d6a7,#81c784,#66bb6a,#4caf50,#43a047,#388e3c,#2e7d32,#1b5e20,#b9f6ca,#69f0ae,#00e676,#00c853'
```
### Configure the Header colours
The header colour is simpler: it is just two colours, to be defined this way:
```yaml
FRONTEND_HEADER_PRIMARY_COLOR: '#FFFFFF'
FRONTEND_HEADER_SECONDARY_COLOR: '#000000'
```
### Configure the Logo
The logo can either be a URL (the URL needs to be accessible from your app), or in the [Image URI format](https://en.wikipedia.org/wiki/Data_URI_scheme) (recommanded).
In order to get an Image URI, you can use the following service: [https://ezgif.com/image-to-datauri](https://ezgif.com/image-to-datauri).
You'll be able to transform any JPEG, PNG or SVG image into this text format, and then set it that way:
```yaml
FRONTEND_LOGO: 'data:image/svg+xml;base64,PD94bWwgdmVyc[...]+Cg=='
```
Alternatively, you can set the logo as a URL:
```yaml
FRONTEND_LOGO: 'https://dorkingtownpartnership.co.uk/wp-content/uploads/2021/10/British-Red-Cross.jpeg'
```
:::info Syntax
Please ensure your value starts with **data:image** and ends with **==**.
The value can be quite long if the image is big.
:::
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion frontend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ VITE_MARKETING_ROOT=
VITE_GOOGLE_ANALYTICS_ID=
VITE_GOOGLE_AD_WORDS_ID=
VITE_GOOGLE_AD_WORDS_CONVERSION_ID=
VITE_AI_FEEDBACK_URL=
VITE_AI_FEEDBACK_URL=
VITE_HEADER_PRIMARY_COLOR=
VITE_PRIMARY_COLOR=
VITE_SECONDARY_COLOR=
VITE_LOGO=
33 changes: 30 additions & 3 deletions frontend/src/Theme.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createTheme } from '@mui/material/styles';
import { PaletteColorOptions, createTheme } from '@mui/material/styles';
import { colors } from '@mui/material';
import config from './utils/getConfig';

const theme = createTheme({
palette: {
primary: colors.deepPurple,
secondary: colors.pink,
primary: convertToColor(config.PRIMARY_COLOR, colors.deepPurple),
secondary: convertToColor(config.SECONDARY_COLOR, colors.pink),
},
components: {
MuiDrawer: {
Expand All @@ -23,3 +24,29 @@ export const Palette = {
};

export default theme;

function convertToColor(
value: string,
defaultColor: PaletteColorOptions
): PaletteColorOptions {
const parts = value.split(',');
if (parts.length !== 14) {
return defaultColor;
}
return {
'50': parts[0],
'100': parts[1],
'200': parts[2],
'300': parts[3],
'400': parts[4],
'500': parts[5],
'600': parts[6],
'700': parts[7],
'800': parts[8],
'900': parts[9],
A100: parts[10],
A200: parts[11],
A400: parts[12],
A700: parts[13],
};
}
10 changes: 10 additions & 0 deletions frontend/src/utils/getConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ interface Config {
VERSION: string;
MARKETING_ROOT: string;
AI_FEEDBACK_URL: string;
PRIMARY_COLOR: string;
SECONDARY_COLOR: string;
HEADER_PRIMARY_COLOR: string;
HEADER_SECONDARY_COLOR: string;
LOGO: string;
}

const ALL_KEYS: (keyof Config)[] = [
Expand All @@ -22,6 +27,11 @@ const ALL_KEYS: (keyof Config)[] = [
'VERSION',
'MARKETING_ROOT',
'AI_FEEDBACK_URL',
'PRIMARY_COLOR',
'SECONDARY_COLOR',
'HEADER_PRIMARY_COLOR',
'HEADER_SECONDARY_COLOR',
'LOGO',
];

declare global {
Expand Down
Loading

0 comments on commit 9b7f255

Please sign in to comment.