Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions dotenv.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


const dotenv = require('dotenv')

const { ENABLE_FRONTEND_TUNNEL, ENABLE_BACKEND_TUNNEL, STAGE } = process.env
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"dynamodb-admin": "^5.1.3",
"eslint": "^9.32.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"husky": "9.1.7",
"lerna": "^7.4.2",
Expand Down
16 changes: 13 additions & 3 deletions packages/backend/src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ const getAvatarURL = (emailHash: string, size?: number): string => {
return size ? `${AVATAR_URL}${emailHash}?s=${size}` : `${AVATAR_URL}${emailHash}`
}

async function hashEmail(email: string) {
const encoder = new TextEncoder()
const data = encoder.encode(email.toLowerCase().trim()) // normalize
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
const hashArray = Array.from(new Uint8Array(hashBuffer))
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
return hashHex
}

/**
* Creates the username from the first and lastname
* @param user User to generate username
Expand All @@ -24,16 +33,17 @@ export const username = (user: Pick<User, 'firstName' | 'lastName'>): string =>
* @param user User to get avatar from
* @returns URL of the avatar
*/
export const avatar = (user: Pick<User, 'email'>): string => {
export const avatar = async (user: Pick<User, 'email'>): Promise<string> => {
if (isDebug() || !AVATAR_URL) {
return `https://avatars.dicebear.com/v2/human/${user.email}.svg`
console.log(hashEmail(user.email))
return `https://api.dicebear.com/9.x/identicon/svg?seed=${await hashEmail(user.email)}.`
}

const email =
OLD_COMPANY_NAME && NEW_COMPANY_NAME
? user.email.toLowerCase().replace(OLD_COMPANY_NAME, NEW_COMPANY_NAME)
: user.email.toLowerCase()
const emailHash = crypto.createHash('md5').update(email).digest('hex').toLowerCase()
const emailHash = await hashEmail(email)

return getAvatarURL(emailHash, 300)
}
8 changes: 6 additions & 2 deletions packages/components/src/accordion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export const StyledAccordionHeader = styled.div`
align-items: center;
`

export const StyledAccordionTitle = styled(Paragraph)<AccordionState>`
export const StyledAccordionTitle = styled(Paragraph).withConfig({
shouldForwardProp: (prop) => !['active'].includes(prop),
})<AccordionState>`
font-size: ${FontSizes.copy};
transition: font-weight 0.1s;
user-select: none;
Expand All @@ -44,7 +46,9 @@ export const StyledAccordionTitle = styled(Paragraph)<AccordionState>`
`}
`

export const StyledAccordionIcon = styled(StyledIcon)<AccordionState>`
export const StyledAccordionIcon = styled(StyledIcon).withConfig({
shouldForwardProp: (prop) => !['active'].includes(prop),
})<AccordionState>`
transform: rotate(${(props) => (props.active ? '180deg' : '0deg')});
transition: all 0.2s;
`
8 changes: 8 additions & 0 deletions packages/components/src/box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Box as BaseBox } from '@rebass/grid'
import { styled } from 'styled-components'

const ignoredProps = new Set(['mt', 'mb', 'ml', 'mr', 'mx', 'my', 'pt', 'pr', 'pl', 'pb', 'px', 'py'])

export const Box = styled(BaseBox).withConfig({
shouldForwardProp: (prop) => !ignoredProps.has(prop),
})``
8 changes: 6 additions & 2 deletions packages/components/src/button-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ const buttonStyle = (props: ButtonLayoutProps) => css`
${props.fullsize && 'width: 100%'};
`

const ButtonWrapper = styled.button<ButtonLayoutProps>`
const ButtonWrapper = styled.button.withConfig({
shouldForwardProp: (prop) => !['styling', 'fullsize'].includes(prop),
})<ButtonLayoutProps>`
font-size: ${FontSizes.button};
border: none;
letter-spacing: 0.2px;
Expand Down Expand Up @@ -223,7 +225,9 @@ const IconWrapper = styled.div`
justify-content: center;
`

const TextWrapper = styled.div<{ hasIcon: boolean }>`
const TextWrapper = styled.div.withConfig({
shouldForwardProp: (prop) => !['hasIcon'].includes(prop),
})<{ hasIcon: boolean }>`
display: flex;
align-items: center;
justify-content: center;
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export interface ContainerProps {
overflow?: 'hidden' | 'scroll' | 'visible'
}

export const Container = styled.div<ContainerProps>`
export const Container = styled.div.withConfig({
shouldForwardProp: (prop) => !['padding', 'paddingX', 'paddingY', 'hoverable', 'flat', 'overflow'].includes(prop),
})<ContainerProps>`
display: block;
overflow: ${(props) => props.overflow || 'hidden'};
background: ${(props) => props.theme.surface};
Expand Down
12 changes: 9 additions & 3 deletions packages/components/src/day-input-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import styled from 'styled-components'
import { FontSizes } from './font-size'
import { Spacings } from './spacing'

const DayInputContainer = styled.div<{ showEntriesInput: boolean }>`
const DayInputContainer = styled.div.withConfig({
shouldForwardProp: (prop) => !['showEntriesInput'].includes(prop),
})<{ showEntriesInput: boolean }>`
padding-bottom: ${(props) => (props.showEntriesInput ? Spacings.xs : Spacings.l)};
padding-top: ${Spacings.l};
`
Expand All @@ -21,7 +23,9 @@ const DayStatusContainer = styled.div`
justify-content: space-between;
`

const StatusContainer = styled.div<{ visible: boolean }>`
const StatusContainer = styled.div.withConfig({
shouldForwardProp: (prop) => !['visible'].includes(prop),
})<{ visible: boolean }>`
display: flex;
align-items: center;
transition: opacity 0.5s ease;
Expand All @@ -33,7 +37,9 @@ const TotalContainer = styled.div`
text-align: right;
`

export const StyledStatusLabel = styled.span<{ error: boolean }>`
export const StyledStatusLabel = styled.span.withConfig({
shouldForwardProp: (prop) => !['error'].includes(prop),
})<{ error: boolean }>`
font-size: ${FontSizes.label};
letter-spacing: 1.2px;
color: ${(props) => (props.error ? props.theme.errorRed : props.theme.mediumFont)};
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/dropdown-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { BorderRadii } from './border-radius'
import { FontSizes } from './font-size'
import { Spacings } from './spacing'

const DropdownContainer = styled.div<{ active?: boolean }>`
const DropdownContainer = styled.div.withConfig({
shouldForwardProp: (prop) => !['active'].includes(prop),
})<{ active?: boolean }>`
display: ${(props) => (props.active ? 'grid' : 'none')};
z-index: 6;
position: fixed;
Expand Down
9 changes: 7 additions & 2 deletions packages/components/src/entry-input-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ interface StyledActionInterface {
noMargin?: boolean
}

export const StyledAction = styled.button<StyledActionInterface>`
export const StyledAction = styled.button.withConfig({
shouldForwardProp: (prop) => !['noMargin', 'danger'].includes(prop),
})<StyledActionInterface>`
display: flex;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -71,7 +73,10 @@ interface EntryContainerProps {
dragFromTopToBottom?: boolean
}

export const StyledEntryContainer = styled.div<EntryContainerProps>`
export const StyledEntryContainer = styled.div.withConfig({
shouldForwardProp: (prop) =>
!['clickable', 'disabled', 'isDragged', 'isDraggedOver', 'dragFromTopToBottom'].includes(prop),
})<EntryContainerProps>`
position: relative;
border-right: 6px solid transparent;
border-left: 6px solid transparent;
Expand Down
25 changes: 25 additions & 0 deletions packages/components/src/flex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Flex as BaseFlex } from '@rebass/grid'
import { styled } from 'styled-components'

const ignoredProps = new Set([
'alignItems',
'flexDirection',
'justifyContent',
'flexWrap',
'mt',
'mb',
'ml',
'mr',
'mx',
'my',
'pt',
'pr',
'pl',
'pb',
'px',
'py',
])

export const Flex = styled(BaseFlex).withConfig({
shouldForwardProp: (prop) => !ignoredProps.has(prop),
})``
12 changes: 9 additions & 3 deletions packages/components/src/heading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,25 @@ const BaseHeader = styled.h1<HeaderProps>`
user-select: none;
`

export const H1 = styled(BaseHeader)`
export const H1 = styled(BaseHeader).withConfig({
shouldForwardProp: (prop) => !['center', 'noMargin'].includes(prop),
})`
font-size: ${FontSizes.h1};
letter-spacing: 0.9px;
${(props) => props.noMargin && 'margin: 0;'};
`

export const H2 = styled.h2<HeaderProps>`
export const H2 = styled.h2.withConfig({
shouldForwardProp: (prop) => !['center', 'noMargin'].includes(prop),
})<HeaderProps>`
font-size: ${FontSizes.h2};
letter-spacing: 0.9px;
${(props) => props.noMargin && 'margin: 0;'};
`

export const Title = styled(BaseHeader)`
export const Title = styled(BaseHeader).withConfig({
shouldForwardProp: (prop) => !['noMargin'].includes(prop),
})`
font-size: ${FontSizes.copy};
${(props) => props.noMargin && 'margin: 0;'};
font-family: ${Fonts.secondary};
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ const findSpacing = (...args: (SpacingKey | undefined)[]) => {
return Spacings[spacing]
}

const IconContainer = styled.i<IconContainerProps>`
const IconContainer = styled.i.withConfig({
shouldForwardProp: (prop) => !['marginLeft', 'marginRight', 'marginTop', 'marginBottom'].includes(prop),
})<IconContainerProps>`
width: ${(props) => props.width || props.size || '100%'};
height: ${(props) => props.height || props.size || 'auto'};
display: block;
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,6 @@ export * from './settings'
export * from './alexa-settings'
export * from './splash-page'
export * from './faq'
export * from './flex'
export * from './box'
export { DefaultTheme, ThemeProvider } from 'styled-components'
4 changes: 3 additions & 1 deletion packages/components/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export enum LoaderSize {
Big = '50px',
}

export const StyledLoaderContainer = styled.div<StyledLoaderProps>`
export const StyledLoaderContainer = styled.div.withConfig({
shouldForwardProp: (prop) => !['padding'].includes(prop),
})<StyledLoaderProps>`
display: flex;
flex: 1;
justify-content: center;
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/modal-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ interface ModalLayoutProps extends ModelStylingProps {
children: ReactNode
}

const ModalOverlay = styled.div<ModalOverlayProps>`
const ModalOverlay = styled.div.withConfig({
shouldForwardProp: (prop) => !['show'].includes(prop),
})<ModalOverlayProps>`
position: fixed;
display: ${(props) => (props.show ? 'flex' : 'none')};
align-items: center;
Expand All @@ -33,7 +35,9 @@ const ModalOverlay = styled.div<ModalOverlayProps>`
padding: 0 ${Spacings.m};
`

const ModalContainer = styled(Container)<ModalContainerProps>`
const ModalContainer = styled(Container).withConfig({
shouldForwardProp: (prop) => !['large'].includes(prop),
})<ModalContainerProps>`
display: flex;
flex-direction: column;
min-width: 300px;
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/navigation-button-link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ export interface StyledLinkProps extends LinkProps {

// isLeft props needs to be removed from LinkProps

const StyledLink = styled(Link).attrs<StyledLinkProps>(({ isLeft: _isLeft }) => ({}))<StyledLinkProps>`
const StyledLink = styled(Link)
.withConfig({
shouldForwardProp: (prop) => !['isLeft'].includes(prop),
})
.attrs<StyledLinkProps>(({ isLeft: _isLeft }) => ({}))<StyledLinkProps>`
display: flex;
align-items: center;
justify-content: center;
Expand Down
26 changes: 16 additions & 10 deletions packages/components/src/navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Link, NavLink, NavLinkProps } from 'react-router'
import styled, { css } from 'styled-components'

import { Flex } from '@rebass/grid'
import { Flex } from './flex'

import { FontSizes } from './font-size'
import { Spacings } from './spacing'

export const StyledNavWrapper = styled(Flex)`
export const StyledNavWrapper = styled(Flex).withConfig({
shouldForwardProp: (prop) => !['flexWrap', 'justifyContent'].includes(prop),
})`
display: flex;
align-items: center;
padding: 0 ${Spacings.l};
Expand Down Expand Up @@ -68,18 +70,21 @@ export const StyledNavItem = styled(({ isMobile: _isMobile, ...rest }: NavItemPr
${(props) =>
!props.isMobile &&
`
&:hover {
&:hover, &.active {
border-bottom: ${Spacings.xxs} solid ${props.theme.iconWhite};
}
`}
${(props) =>
props.isMobile &&
`
color: ${props.theme.darkFont};
&:hover {
opacity: 1;
}
&.active {
border-bottom: ${Spacings.xxs} solid ${props.theme.iconDarkGrey};
}
`}
&.active {
border-bottom: ${Spacings.xxs} solid ${(props) => props.theme.iconWhite};
}
${(props) => props.isMobile && StyledMobileNavItemStyle}
`

Expand All @@ -88,14 +93,15 @@ export const StyledLogoutItem = styled.div`
display: flex;
align-items: center;
text-decoration: none;
color: ${(props) => props.theme.headerFont};
color: ${(props) => props.theme.darkFont};
font-size: ${FontSizes.copy};
transition: 0.1s all;
opacity: 0.8;
${StyledMobileNavItemStyle}

:hover {
&:hover {
cursor: pointer;
opacity: 1;
color: ${(props) => props.theme.buttonSecondaryDangerHovered};
}
`

Expand Down Expand Up @@ -137,7 +143,7 @@ export const StyledLink = styled.div`

export const StyledMobileNavWrapper = styled.div`
width: 100vw;
background-color: ${(props) => props.theme.buttonPrimaryFont};
background: ${(props) => props.theme.background};
position: fixed;
z-index: 5;
display: flex;
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/new-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ export interface InputProps {
block?: boolean
}

export const Input = styled.input<InputProps>`
export const Input = styled.input.withConfig({
shouldForwardProp: (prop) => !['block', 'error'].includes(prop),
})<InputProps>`
width: ${(props) => props.block && '100%'};
background: ${(props) => props.theme.inputBackground};
padding: ${Spacings.m};
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export interface ParagraphProps {
margin?: string
}

export const Paragraph = styled.p<ParagraphProps>`
export const Paragraph = styled.p.withConfig({
shouldForwardProp: (prop) => !['center', 'noMargin'].includes(prop),
})<ParagraphProps>`
line-height: 1.4;
color: ${(props) => (props.color ? props.theme[props.color] : props.theme.lightFont)};
font-family: ${(props) => props.font || Fonts.primary};
Expand Down
Loading