Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create campaign application organizer form (Epic #1842) #1863

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
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>
)
}
Loading