-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨(frontend) add meeting register form
add a form which enables the user to register the meeting
- Loading branch information
karabij
committed
Dec 12, 2022
1 parent
26278f4
commit 85072a9
Showing
31 changed files
with
1,049 additions
and
298 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 0 additions & 24 deletions
24
...magnify/src/components/design-system/Formik/FormikDatePicker/FormikDatePicker.stories.tsx
This file was deleted.
Oops, something went wrong.
102 changes: 0 additions & 102 deletions
102
...rontend/magnify/src/components/design-system/Formik/FormikDatePicker/FormikDatePicker.tsx
This file was deleted.
Oops, something went wrong.
1 change: 0 additions & 1 deletion
1
src/frontend/magnify/src/components/design-system/Formik/FormikDatePicker/index.ts
This file was deleted.
Oops, something went wrong.
30 changes: 30 additions & 0 deletions
30
...src/components/design-system/Formik/FormikDateTimePicker/FormikDateTimePicker.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import withFormik from '@bbbtech/storybook-formik'; | ||
import { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
import React from 'react'; | ||
import { useIntl } from 'react-intl'; | ||
import { getSuggestions } from '../../../meetings/RegisterMeetingForm/utils'; | ||
import FormikDateTimePicker from './FormikDateTimePicker'; | ||
|
||
export default { | ||
title: 'Formik/DateTimePicker', | ||
component: FormikDateTimePicker, | ||
decorators: [withFormik], | ||
initialValues: { date: new Date() }, | ||
} as ComponentMeta<typeof FormikDateTimePicker>; | ||
|
||
const Template: ComponentStory<typeof FormikDateTimePicker> = (args, context) => ( | ||
<div> | ||
{context.parameters.title} | ||
<FormikDateTimePicker {...args} /> | ||
</div> | ||
); | ||
|
||
export const basicDateTimePicker = Template.bind({}); | ||
const intl = useIntl(); | ||
|
||
basicDateTimePicker.args = { | ||
timeName: 'time', | ||
dateName: 'date', | ||
frenchSuggestions: getSuggestions('fr'), | ||
localTimeSuggestions: getSuggestions(intl.locale), | ||
}; |
124 changes: 124 additions & 0 deletions
124
...magnify/src/components/design-system/Formik/FormikDateTimePicker/FormikDateTimePicker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { ErrorMessage, useField, useFormikContext } from 'formik'; | ||
import { DateInput, DropButton, Box, Text } from 'grommet'; | ||
import { CaretDown } from 'grommet-icons'; | ||
import { DateTime, Settings } from 'luxon'; | ||
import React, { FunctionComponent, useState } from 'react'; | ||
import { useIntl } from 'react-intl'; | ||
import TimePicker, { TimePickerValue } from 'react-time-picker'; | ||
import SuggestionButton from './SuggestionButton'; | ||
|
||
export interface formikDateTimePickerProps { | ||
dateName: string; | ||
timeName: string; | ||
frenchSuggestions: string[]; | ||
localTimeSuggestions: string[]; | ||
label: string; | ||
} | ||
|
||
const nextYear = new Date(); | ||
nextYear.setFullYear(new Date().getFullYear() + 1); | ||
|
||
const FormikDateTimePicker: FunctionComponent<formikDateTimePickerProps> = ({ ...props }) => { | ||
const [open, setOpen] = useState<boolean | undefined>(undefined); | ||
const [dateField] = useField(props.dateName); | ||
const [timeField] = useField(props.timeName); | ||
|
||
const formikContext = useFormikContext(); | ||
const intl = useIntl(); | ||
Settings.defaultLocale = intl.locale; | ||
|
||
const isToday = | ||
DateTime.fromISO(dateField.value).toFormat('MM-dd-yyyy') == | ||
DateTime.now().toFormat('MM-dd-yyyy'); | ||
const beforeToday = | ||
DateTime.fromISO(dateField.value).toFormat('MM-dd-yyyy') < | ||
DateTime.now().toFormat('MM-dd-yyyy'); | ||
|
||
const onTimeChange = (value: string) => { | ||
formikContext.setFieldValue(props.timeName, value.toString()); | ||
setOpen(false); | ||
}; | ||
|
||
const onDateChange = (event: { value: string | string[] }) => { | ||
let value: string; | ||
if (Array.isArray(event.value)) { | ||
value = ''; | ||
if (event.value.length > 0) { | ||
value = event.value[0]; | ||
} | ||
} else { | ||
value = event.value; | ||
} | ||
formikContext.setFieldValue(props.dateName, value); | ||
}; | ||
|
||
React.useEffect(() => { | ||
console.log(formikContext.errors, formikContext.values); | ||
}, [formikContext.values, formikContext.errors]); | ||
|
||
const suggestionButtons = props.localTimeSuggestions.map((value: string, index: number) => ( | ||
<SuggestionButton | ||
key={value} | ||
beforeToday={beforeToday} | ||
buttonValue={value} | ||
choiceValue={timeField.value} | ||
frenchButtonValue={props.frenchSuggestions[index]} | ||
isToday={isToday} | ||
onClick={onTimeChange} | ||
/> | ||
)); | ||
|
||
return ( | ||
<Box gap={'5px'}> | ||
{props.label != '' && ( | ||
<label htmlFor={props.dateName}> | ||
<Text size={'xsmall'} weight={'bold'}> | ||
{props.label} | ||
</Text> | ||
</label> | ||
)} | ||
<div> | ||
<Box align="center" basis="1" direction="column" gap="small"> | ||
<DateInput | ||
{...dateField} | ||
format={intl.locale === 'fr' ? 'jj/mm/aaaa' : 'yyyy/mm/dd'} | ||
name={props.dateName} | ||
onChange={onDateChange} | ||
value={dateField.value ? new Date(dateField.value).toISOString() : ''} | ||
calendarProps={{ | ||
bounds: [new Date().toISOString(), nextYear.toISOString()], | ||
size: 'small', | ||
}} | ||
></DateInput> | ||
|
||
<Box align="center" direction="row" gap="small"> | ||
<TimePicker | ||
{...timeField} | ||
disableClock | ||
locale={intl.locale} | ||
name={props.timeName} | ||
onChange={(value: TimePickerValue) => onTimeChange(value.toString())} | ||
></TimePicker> | ||
<DropButton | ||
dropAlign={{ top: 'bottom' }} | ||
onClose={() => setOpen(false)} | ||
open={open} | ||
dropContent={ | ||
<Box align="center" basis="small" direction="column" gap="5px"> | ||
{suggestionButtons} | ||
</Box> | ||
} | ||
onOpen={() => { | ||
setOpen(true); | ||
}} | ||
> | ||
<CaretDown size="15px" /> | ||
</DropButton> | ||
</Box> | ||
</Box> | ||
</div> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default FormikDateTimePicker; |
44 changes: 44 additions & 0 deletions
44
...end/magnify/src/components/design-system/Formik/FormikDateTimePicker/SuggestionButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { Box, Button, Text } from 'grommet'; | ||
import { normalizeColor } from 'grommet/utils'; | ||
import React, { FunctionComponent, ReactElement } from 'react'; | ||
import { useTheme } from 'styled-components'; | ||
import { mergeDateTime } from './utils'; | ||
|
||
const today = new Date().toISOString(); | ||
|
||
export interface suggestionButtonProps { | ||
buttonValue: string; | ||
frenchButtonValue: string; | ||
choiceValue: string; | ||
onClick: (value: string) => void; | ||
isToday: boolean; | ||
beforeToday: boolean; | ||
} | ||
|
||
const SuggestionButton: FunctionComponent<suggestionButtonProps> = ({ ...props }): ReactElement => { | ||
const isChosenButton: boolean = props.frenchButtonValue == props.choiceValue; | ||
const chosenDateTime = mergeDateTime(today, props.frenchButtonValue); | ||
const isButtonBeforeNow: boolean = chosenDateTime ? chosenDateTime < today : false; | ||
const theme = useTheme(); | ||
return ( | ||
<Button | ||
color={isChosenButton ? `${normalizeColor('light-2', theme)}` : 'black'} | ||
disabled={props.beforeToday || (props.isToday && isButtonBeforeNow)} | ||
fill={isChosenButton ? 'horizontal' : false} | ||
justify="center" | ||
margin={{ top: 'xsmall' }} | ||
primary={isChosenButton} | ||
onClick={() => { | ||
props.onClick(props.frenchButtonValue); | ||
}} | ||
> | ||
<Box alignContent="center" alignSelf="center"> | ||
<Text color="black" textAlign="center"> | ||
{props.buttonValue} | ||
</Text> | ||
</Box> | ||
</Button> | ||
); | ||
}; | ||
|
||
export default SuggestionButton; |
1 change: 1 addition & 0 deletions
1
src/frontend/magnify/src/components/design-system/Formik/FormikDateTimePicker/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default, formikDateTimePickerProps } from '../FormikDateTimePicker/FormikDateTimePicker'; |
31 changes: 31 additions & 0 deletions
31
src/frontend/magnify/src/components/design-system/Formik/FormikDateTimePicker/utils.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { DateTime, Duration } from 'luxon'; | ||
|
||
export const splitDateTime = (dateTimeISO: string | null): { date: string; time: string } => { | ||
if (!dateTimeISO) { | ||
return { date: '', time: '' }; | ||
} | ||
const dateTime = DateTime.fromISO(dateTimeISO); | ||
return { | ||
date: dateTime.toISODate(), | ||
time: dateTime.toLocaleString(DateTime.TIME_24_SIMPLE), | ||
}; | ||
}; | ||
|
||
export const mergeDateTime = ( | ||
dateString: string | null, | ||
timeString: string | null, | ||
): string | null => { | ||
if (!dateString || !timeString) { | ||
return null; | ||
} | ||
try { | ||
const time = Duration.fromISOTime(timeString); | ||
const dateTime = DateTime.fromISO(dateString).set({ | ||
hour: time.hours, | ||
minute: time.minutes, | ||
}); | ||
return dateTime.toISO(); | ||
} catch (e) { | ||
return null; | ||
} | ||
}; |
Oops, something went wrong.