Skip to content

Commit

Permalink
feat: create campaign application organizer form (Epic #1842) (#1863)
Browse files Browse the repository at this point in the history
* feat: add remark in the stepper

* add translations for step one

* refactor action buttons styles

* create CampaignApplicationOrganizer component

* edit CampaignApplicationOrganizer

* add yup validation to campaign application organizer form

* fix styles to be responsive

* fix: adjust spacing between fields and buttons to be the same

* refactor organizer step form according to endpoint schema

* refactor action buttons styles
  • Loading branch information
teodorazhelyazkova authored Jun 26, 2024
1 parent 9552937 commit 8c6e1a0
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 39 deletions.
16 changes: 16 additions & 0 deletions public/locales/bg/campaign-application.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
{
"steps": {
"organizer": {
"title": "Организатор",
"name": "Вашите име и фамилия",
"phone": "Телефон за връзка",
"email": "Email"
}
},
"cta": {
"next": "Запазете и продължете",
"back": "Назад"
},
"remark": {
"part-one": "*Допълнителна информация за процеса на кандидатстване и неговите етапи можете да намерите в нашите ",
"part-two": "и в секцията ",
"links": {
"terms": "Общи условия ",
"faq": "Често задавани въпроси"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { useCallback, useState } from 'react'

import { Grid, StepLabel } from '@mui/material'

import { Step as StepType, Steps } from './helpers/campaignApplication.types'
import {
CampaignApplicationFormData,
Step as StepType,
Steps,
} from './helpers/campaignApplication.types'

import GenericForm from 'components/common/form/GenericForm'
import CampaignApplicationStepperIcon from './CampaignApplicationStepperIcon'
Expand All @@ -13,14 +17,21 @@ import CampaignApplicationFormActions from './CampaignApplicationFormActions'
import CampaignApplicationRemark from './CampaignApplicationRemark'
import stepsHandler from './helpers/stepsHandler'

import { validationSchema } from './helpers/validation-schema'

import {
ActionsContainer,
StyledCampaignApplicationStep,
StyledCampaignApplicationStepper,
StyledStepConnector,
} from './helpers/campaignApplication.styled'

const initialValues: Record<string, string> = {}
const initialValues: CampaignApplicationFormData = {
organizer: {
name: '',
phone: '',
email: '',
},
}

const steps: StepType[] = [
{
Expand Down Expand Up @@ -50,7 +61,10 @@ export default function CampaignApplicationForm() {

return (
<>
<GenericForm<Record<string, string>> onSubmit={handleSubmit} initialValues={initialValues}>
<GenericForm<CampaignApplicationFormData>
onSubmit={handleSubmit}
initialValues={initialValues}
validationSchema={validationSchema[activeStep]}>
<StyledCampaignApplicationStepper
activeStep={activeStep}
connector={<StyledStepConnector />}>
Expand All @@ -60,14 +74,14 @@ export default function CampaignApplicationForm() {
</StyledCampaignApplicationStep>
))}
</StyledCampaignApplicationStepper>
<ActionsContainer container spacing={5}>
<Grid container>
<Grid container item xs={12}>
{activeStep < steps.length && steps[activeStep].component}
</Grid>
<Grid container item spacing={3}>
<Grid container item alignContent="center">
<CampaignApplicationFormActions activeStep={activeStep} onBack={handleBack} />
</Grid>
</ActionsContainer>
</Grid>
</GenericForm>
{(activeStep === Steps.ORGANIZER || activeStep === Steps.CAMPAIGN) && (
<CampaignApplicationRemark />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,28 @@ export default function CampaignApplicationFormActions({
const { t } = useTranslation('campaign-application')

return (
<Root container item xs={12} spacing={3} justifyContent="space-between">
<Grid item sx={{ textAlign: 'left' }}>
<Root container item xs={12} spacing={6} justifyContent="space-between">
<Grid item xs={12} md={6} flexWrap="nowrap">
{activeStep === 0 ? (
<ActionLinkButton
fullWidth
href=""
variant="outlined"
startIcon={<ArrowBackIosIcon fontSize="small" />}>
{t('cta.back')}
</ActionLinkButton>
) : (
<ActionButton onClick={onBack} startIcon={<ArrowBackIosIcon fontSize="small" />}>
<ActionButton
fullWidth
onClick={onBack}
startIcon={<ArrowBackIosIcon fontSize="small" />}>
{t('cta.back')}
</ActionButton>
)}
</Grid>
<Grid item>
<Grid item xs={12} md={6} flexWrap="nowrap">
<ActionSubmitButton
fullWidth
label={t('cta.next')}
endIcon={<ArrowForwardIosIcon fontSize="small" />}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import CampaignApplicationForm from './CampaignApplicationForm'

export default function CampaignApplicationPage() {
return (
<Layout maxWidth="md">
<Layout maxWidth="md" sx={{ paddingInline: 5 }}>
<CampaignApplicationForm />
</Layout>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { styled } from '@mui/material/styles'
import { Grid, Step, StepConnector, Stepper } from '@mui/material'

import Heading from 'components/common/Heading'
import FormTextField from 'components/common/form/FormTextField'
import theme from 'common/theme'

export const StyledCampaignApplicationStep = styled(Step)(() => ({
Expand Down Expand Up @@ -54,8 +55,12 @@ export const StyledCampaignApplicationStepperIcon = styled(Grid)(() => ({
fontSize: theme.typography.pxToRem(36),
}))

export const ActionsContainer = styled(Grid)(() => ({
display: 'flex',
justifyContent: 'center',
marginTop: theme.spacing(1),
export const StyledStepHeading = styled(Heading)(() => ({
fontWeight: 600,
paddingBlock: theme.spacing(5),
}))

export const StyledFormTextField = styled(FormTextField)(() => ({
borderRadius: theme.borders.round,
height: theme.spacing(5),
}))
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Person } from 'gql/person'

export type Step = {
title: string
component: JSX.Element
Expand All @@ -9,3 +11,20 @@ export enum Steps {
CAMPAIGN = 1,
CAMPAIGN_DETAILS = 2,
}

export type CampaignApplicationOrganizer = {
name: string
phone: string
email: string
}

export type CampaignApplicationFormData = {
organizer: CampaignApplicationOrganizer
}

export type CampaignApplicationFormDataSteps = {
[Steps.NONE]: never
[Steps.ORGANIZER]: {
organizer: CampaignApplicationOrganizer
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,31 @@ import SubmitButton from 'components/common/form/SubmitButton'

import theme from 'common/theme'

const commonButtonStyles = {
padding: theme.spacing(1, 5),
border: `1px solid ${theme.palette.common.black}`,
borderRadius: theme.borders.round,
color: theme.palette.common.black,
fontSize: theme.typography.pxToRem(15),
fontWeight: 800,
}

export const Root = styled(Grid)(() => ({
marginTop: theme.spacing(15),
textAlign: 'center',
}))

export const ActionLinkButton = styled(LinkButton)(() => ({
...commonButtonStyles,
backgroundColor: theme.palette.common.white,
border: `1px solid ${theme.palette.common.black}`,
padding: theme.spacing(1, 5),
borderRadius: theme.borders.round,
color: theme.palette.common.black,
fontSize: theme.typography.pxToRem(20),
width: theme.spacing(50),
fontWeight: 800,
}))

export const ActionButton = styled(Button)(() => ({
...commonButtonStyles,
backgroundColor: theme.palette.common.white,
border: `1px solid ${theme.palette.common.black}`,
padding: theme.spacing(1, 5),
borderRadius: theme.borders.round,
color: theme.palette.common.black,
fontSize: theme.typography.pxToRem(20),
width: theme.spacing(50),
fontWeight: 800,
}))

export const ActionSubmitButton = styled(SubmitButton)(() => ({
...commonButtonStyles,
backgroundColor: '#62C4FB',
border: `1px solid ${theme.palette.common.black}`,
padding: theme.spacing(1, 5),
borderRadius: theme.borders.round,
color: theme.palette.common.black,
fontSize: theme.typography.pxToRem(20),
width: theme.spacing(50),
fontWeight: 800,
}))
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as yup from 'yup'

import { name, phone, email } from 'common/form/validation'

import {
CampaignApplicationFormDataSteps,
CampaignApplicationOrganizer,
Steps,
} from './campaignApplication.types'

const organizer: yup.SchemaOf<CampaignApplicationOrganizer> = yup
.object()
.shape({
name: name.required(),
phone: phone.required(),
email: email.required(),
})
.defined()

export const validationSchema: {
[key in Steps]?:
| yup.SchemaOf<CampaignApplicationFormDataSteps[Steps.NONE]>
| yup.SchemaOf<CampaignApplicationFormDataSteps[Steps.ORGANIZER]>
} = {
[Steps.NONE]: undefined,
[Steps.ORGANIZER]: yup.object().shape({
organizer: organizer.required(),
}),
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
import { useTranslation } from 'next-i18next'

import { Grid } from '@mui/material'

import { StyledStepHeading, StyledFormTextField } from '../helpers/campaignApplication.styled'

export default function CampaignApplicationOrganizer() {
return <div>Campaign Application Organizer</div>
const { t } = useTranslation('campaign-application')

return (
<Grid container spacing={6} justifyContent="center" direction="column" alignContent="center">
<Grid item container justifyContent="center">
<StyledStepHeading variant="h4">{t('steps.organizer.title')}</StyledStepHeading>
</Grid>
<Grid item container spacing={6} justifyContent="space-between" direction="row">
<Grid item xs={12} flexWrap="nowrap">
<StyledFormTextField
label={t('steps.organizer.name')}
type="text"
name="organizer.name"
autoComplete="name"
/>
</Grid>
</Grid>
<Grid item container spacing={6} justifyContent="space-between" direction="row">
<Grid container item xs={12} md={6} flexWrap="nowrap">
<StyledFormTextField
label={t('steps.organizer.phone')}
type="phone"
name="organizer.phone"
autoComplete="tel"
/>
</Grid>
<Grid container item xs={12} md={6} flexWrap="nowrap">
<StyledFormTextField
label={t('steps.organizer.email')}
type="email"
name="organizer.email"
autoComplete="email"
/>
</Grid>
</Grid>
</Grid>
)
}

0 comments on commit 8c6e1a0

Please sign in to comment.