Skip to content

Commit

Permalink
Feat: onboarding create join project (#53)
Browse files Browse the repository at this point in the history
Adds project screens and some reusable components for onboarding as well as a logic file and a test. Fixes spacing to be in line with design guidelines.
  • Loading branch information
cimigree authored Dec 12, 2024
1 parent 7e62b7f commit 45c576c
Show file tree
Hide file tree
Showing 25 changed files with 1,051 additions and 317 deletions.
59 changes: 58 additions & 1 deletion messages/renderer/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,32 @@
"components.OnboardingTopMenu.step": {
"message": "Step {number}"
},
"screens.CreateJoinProjectScreen.askToJoin": {
"message": "Ask a monitoring coordinator to join their Project."
},
"screens.CreateJoinProjectScreen.createProject": {
"message": "Create a Project"
},
"screens.CreateJoinProjectScreen.limitedToDevices": {
"message": "Sharing observations and data are limited to devices within each Project."
},
"screens.CreateJoinProjectScreen.securelyStore": {
"message": "Projects help teams securely store and share their territory monitoring data and observations."
},
"screens.CreateJoinProjectScreen.startNewProject": {
"message": "Starting a new territory monitoring project?"
},
"screens.CreateJoinProjectScreen.title": {
"message": "Join a Project"
},
"screens.DataPrivacy.description": {
"message": "CoMapeo allows teams to map offline without needing internet servers."
},
"screens.DataPrivacy.diagnostic": {
"message": "Private by default — diagnostic information is made fully anonymous and you can opt-out any time."
},
"screens.DataPrivacy.encrypted": {
"message": "All data stays fully encrypted"
"message": "All data stays fully encrypted."
},
"screens.DataPrivacy.learnMore": {
"message": "Learn More"
Expand Down Expand Up @@ -68,6 +86,18 @@
"screens.IntroToCoMapeo.viewAndManage": {
"message": "View and manage observations in CoMapeo Mobile Projects."
},
"screens.JoinProjectScreen.declineInvite": {
"message": "Decline Invite"
},
"screens.JoinProjectScreen.invitedTitle": {
"message": "You've been invited to join"
},
"screens.JoinProjectScreen.joinProject": {
"message": "Join Project"
},
"screens.JoinProjectScreen.title": {
"message": "Join"
},
"screens.OnboardingPrivacyPolicy.permissionsTitle": {
"message": "Current Permissions"
},
Expand Down Expand Up @@ -181,5 +211,32 @@
},
"screens.PrivacyPolicy.whyCollectedDescription": {
"message": "Crash data and app errors together with the device and app info provide Awana Digital with the information we need to fix errors and bugs in the app. The performance data helps us improve the responsiveness of the app and identify errors. User counts, including total users, users per country, and users per project, help justify ongoing investment in the development of CoMapeo."
},
"screens.ProjectCreationScreen.addName": {
"message": "Create Project"
},
"screens.ProjectCreationScreen.advancedProjectSettings": {
"message": "Advanced Project Settings"
},
"screens.ProjectCreationScreen.characterCount": {
"message": "{count}/{maxLength}"
},
"screens.ProjectCreationScreen.enterNameLabel": {
"message": "Name your project"
},
"screens.ProjectCreationScreen.errorSavingProjectName": {
"message": "An error occurred while saving your project name. Please try again."
},
"screens.ProjectCreationScreen.importConfig": {
"message": "Import Config"
},
"screens.ProjectCreationScreen.placeholder": {
"message": "Project Name"
},
"screens.ProjectCreationScreen.saving": {
"message": "Saving..."
},
"screens.ProjectCreationScreen.title": {
"message": "Create a Project"
}
}
2 changes: 1 addition & 1 deletion src/renderer/src/Theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const theme = createTheme({
borderWidth: 1,
},
}),
borderRadius: 4,
borderRadius: 32,
textTransform: 'none',
fontSize: '1rem',
fontWeight: 400,
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ export const Button = ({
variant = 'contained',
style,
disabled,
className,
...props
}: CustomButtonProps) => {
const propsBasedOnSize = size === 'fullWidth' ? { fullWidth: true } : { size }
return (
<MuiButton
className={className}
color={color}
variant={variant}
style={style}
Expand Down
55 changes: 55 additions & 0 deletions src/renderer/src/components/Onboarding/OnboardingScreenLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { type ReactNode } from 'react'
import { styled } from '@mui/material/styles'

import { BLUE_GREY, DARK_COMAPEO_BLUE } from '../../colors'

const Container = styled('div')({
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
backgroundColor: DARK_COMAPEO_BLUE,
})

const ContentWrapper = styled('div')({
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
})

const ContentBox = styled('div')({
position: 'relative',
backgroundColor: 'rgba(255, 255, 255, 0.94)',
border: `1px solid ${BLUE_GREY}`,
borderRadius: 8,
padding: 20,
maxWidth: 800,
width: '55%',
textAlign: 'center',
boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.02)',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
minHeight: 700,
overflow: 'hidden',
})

interface OnboardingScreenLayoutProps {
topMenu?: ReactNode
children?: ReactNode
}

export function OnboardingScreenLayout({
topMenu,
children,
}: OnboardingScreenLayoutProps) {
return (
<Container>
{topMenu}
<ContentWrapper>
<ContentBox>{children}</ContentBox>
</ContentWrapper>
</Container>
)
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
import { styled } from '@mui/material/styles'
import { useNavigate, useRouter } from '@tanstack/react-router'
import { defineMessages, useIntl } from 'react-intl'

import { BLACK, BLUE_GREY, COMAPEO_BLUE, WHITE } from '../colors'
import { Button } from './Button'
import { Text } from './Text'
import { BLACK, BLUE_GREY, COMAPEO_BLUE, WHITE } from '../../colors'
import { Button } from '../Button'
import { Text } from '../Text'

const MenuContainer = styled('div')({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '55%',
margin: '16px auto',
margin: '20px auto',
position: 'relative',
})
const GoBackButton = styled(Button)({
display: 'flex',
alignItems: 'center',
gap: 8,
backgroundColor: 'transparent',
const GoBackButton = styled(Button)<{ disabled?: boolean }>(({ disabled }) => ({
gap: 12,
color: BLUE_GREY,
fontSize: 16,
padding: '12px 32px',
borderRadius: 20,
whiteSpace: 'nowrap',
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
},
})
cursor: disabled ? 'default' : 'pointer',
}))
const BackArrow = styled('span')({
fontSize: 24,
color: WHITE,
Expand All @@ -39,15 +29,18 @@ const StepsContainer = styled('div')({
const Steps = styled('div')({
display: 'flex',
alignItems: 'center',
gap: 16,
gap: 12,
})
const Step = styled('div')(({ active }: { active: boolean }) => ({
const Step = styled('div')<{
active: boolean
}>(({ active }) => ({
backgroundColor: active ? WHITE : 'transparent',
color: active ? BLACK : BLUE_GREY,
padding: '12px 32px',
borderRadius: 20,
fontWeight: active ? 'bold' : 'normal',
whiteSpace: 'nowrap',
cursor: 'default',
}))
const Divider = styled('div')({
width: 16,
Expand All @@ -59,6 +52,7 @@ const Divider = styled('div')({

interface OnboardingTopMenuProps {
currentStep: number
onBackPress?: () => void
}

const m = defineMessages({
Expand All @@ -72,40 +66,33 @@ const m = defineMessages({
},
})

export function OnboardingTopMenu({ currentStep }: OnboardingTopMenuProps) {
const navigate = useNavigate()
const router = useRouter()
export function OnboardingTopMenu({
currentStep,
onBackPress,
}: OnboardingTopMenuProps) {
const { formatMessage } = useIntl()
const stepToRoute: Record<number, string> = {
1: 'DataPrivacy',
2: 'DeviceNamingScreen',
3: 'CreateJoinProjectScreen',
}

return (
<MenuContainer>
<GoBackButton
onClick={() => router.history.back()}
onClick={onBackPress}
variant="text"
style={{
color: BLUE_GREY,
gap: 8,
padding: '12px 32px',
}}
aria-label={formatMessage(m.goBack)}
disabled={!onBackPress}
sx={{
'&.Mui-disabled': {
color: BLUE_GREY,
opacity: 0.5,
},
}}
>
<BackArrow aria-hidden="true"></BackArrow>
{formatMessage(m.goBack)}
</GoBackButton>
<Steps>
{[1, 2, 3].map((step) => (
<StepsContainer key={step}>
<Step
active={currentStep === step}
onClick={() =>
navigate({ to: `/Onboarding/${stepToRoute[step]}` })
}
>
<Step active={currentStep === step}>
<Text kind="body" bold={currentStep === step}>
{formatMessage(m.step, { number: step })}
</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import CircleIcon from '@mui/icons-material/Circle'
import { styled } from '@mui/material/styles'

import { DARK_GREY } from '../../colors'
import { Text } from '../../components/Text'
import { DARK_GREY } from '../../../colors'
import { Text } from '../../Text'

const DiagnosticsItem = styled('div')({
display: 'flex',
flexDirection: 'row',
alignItems: 'flex-start',
gap: 8,
gap: 12,
marginBottom: 12,
paddingLeft: 12,
})
const DiagnosticsTitle = styled(Text)({
fontWeight: 'bold',
marginRight: 4,
marginRight: 12,
color: DARK_GREY,
lineHeight: 1,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Checkbox from '@mui/material/Checkbox'
import { styled } from '@mui/material/styles'
import { defineMessages, useIntl } from 'react-intl'

import { BLACK } from '../../colors'
import { BLACK } from '../../../colors'

const m = defineMessages({
shareDiagnostics: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'
import { styled } from '@mui/material/styles'

import { BLACK, DARK_GREY } from '../../colors'
import { Text } from '../Text'
import { BLACK, DARK_GREY } from '../../../colors'
import { Text } from '../../Text'

const Container = styled('div')({
gap: 20,
gap: 12,
paddingBottom: 20,
displau: 'flex',
})
Expand All @@ -14,7 +14,7 @@ const PointHeader = styled('div')({
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: 10,
gap: 12,
})

const PointTitle = styled(Text)({
Expand Down
Loading

0 comments on commit 45c576c

Please sign in to comment.