Skip to content

Commit

Permalink
feat: add timezone components
Browse files Browse the repository at this point in the history
  • Loading branch information
RabahZeineddine committed Oct 12, 2023
1 parent 6d8d1ad commit f71db9b
Show file tree
Hide file tree
Showing 19 changed files with 551 additions and 64 deletions.
82 changes: 44 additions & 38 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
# Table of contents

* [Home](README.md)
- [Home](README.md)

## Components

* [Datagrid](components/datagrid.md)
* [Fields](components/fields/README.md)
* [BooleanField](components/fields/booleanfield.md)
* [ChipField](components/fields/chipfield.md)
* [CountryField](components/fields/countryfield.md)
* [CurrencyField](components/fields/currencyfield.md)
* [DateField](components/fields/datefield.md)
* [FileViewerField](components/fields/fileviewerfield.md)
* [MaskedNumberField](components/fields/maskednumberfield.md)
* [PhoneField](components/fields/phonefield.md)
* [ReferenceArrayField](components/fields/referencearrayfield.md)
* [ReferenceField](components/fields/referencefield.md)
* [RichTextField](components/fields/richtextfield.md)
* [SelectField](components/fields/selectfield.md)
* [TextField](components/fields/textfield.md)
* [TimeField](components/fields/timefield.md)
* [TimelineArrayField](components/fields/timelinearrayfield.md)
* [Inputs](components/inputs/README.md)
* [CountryInput](components/inputs/countryinput.md)
* [CurrencyInput](components/inputs/currencyinput.md)
* [DateInput](components/inputs/dateinput.md)
* [MapsInput](components/inputs/mapsinput.md)
* [MaskedNumberInput](components/inputs/maskednumberinput.md)
* [MaskedTextInput](components/inputs/maskedtextinput.md)
* [PhoneInput](components/inputs/phoneinput.md)
* [PlacesTimelineInput](components/inputs/placestimelineinput.md)
* [TimeInput](components/inputs/timeinput.md)
* [ResponsiveDatagrid](components/responsivedatagrid.md)
- [Datagrid](components/datagrid.md)
- [Fields](components/fields/README.md)
- [BooleanField](components/fields/booleanfield.md)
- [ChipField](components/fields/chipfield.md)
- [CountryField](components/fields/countryfield.md)
- [CurrencyField](components/fields/currencyfield.md)
- [DateField](components/fields/datefield.md)
- [FileViewerField](components/fields/fileviewerfield.md)
- [MaskedNumberField](components/fields/maskednumberfield.md)
- [PhoneField](components/fields/phonefield.md)
- [ReferenceArrayField](components/fields/referencearrayfield.md)
- [ReferenceField](components/fields/referencefield.md)
- [RichTextField](components/fields/richtextfield.md)
- [SelectField](components/fields/selectfield.md)
- [TextField](components/fields/textfield.md)
- [TimeField](components/fields/timefield.md)
- [TimelineArrayField](components/fields/timelinearrayfield.md)
- [TimezoneField](components/fields/timezonefield.md)
- [TzTimeField](components/fields/tztimefield.md)
- [TzDateField](components/fields/tzdatefield.md)
- [Inputs](components/inputs/README.md)
- [CountryInput](components/inputs/countryinput.md)
- [CurrencyInput](components/inputs/currencyinput.md)
- [DateInput](components/inputs/dateinput.md)
- [MapsInput](components/inputs/mapsinput.md)
- [MaskedNumberInput](components/inputs/maskednumberinput.md)
- [MaskedTextInput](components/inputs/maskedtextinput.md)
- [PhoneInput](components/inputs/phoneinput.md)
- [PlacesTimelineInput](components/inputs/placestimelineinput.md)
- [TimeInput](components/inputs/timeinput.md)
- [TimezoneInput](components/fields/timezoneinput.md)
- [TzTimeInput](components/fields/tztimeinput.md)
- [TzDateInput](components/fields/tzdateinput.md)
- [ResponsiveDatagrid](components/responsivedatagrid.md)

## Hooks

* [useScreenSize](hooks/usescreensize.md)
* [useCurrencies](hooks/usecurrencies.md)
* [useCountries](hooks/usecountries.md)
- [useScreenSize](hooks/usescreensize.md)
- [useCurrencies](hooks/usecurrencies.md)
- [useCountries](hooks/usecountries.md)

## Services

* [HttpRequest](services/httprequest.md)
* [LocalSession](services/localsession.md)
* [raDataRestProvider](services/radatarestprovider.md)
- [HttpRequest](services/httprequest.md)
- [LocalSession](services/localsession.md)
- [raDataRestProvider](services/radatarestprovider.md)

## Providers

* [DataProvider](providers/dataprovider.md)
- [DataProvider](providers/dataprovider.md)

## Validations

* [minYear](validations/minyear.md)
* [maxYear](validations/maxyear.md)
- [minYear](validations/minyear.md)
- [maxYear](validations/maxyear.md)
19 changes: 19 additions & 0 deletions docs/components/fields/timezonefield.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TimezoneField

TimezoneField component that map IANA timezone to text with Labeled component.

### Usage

```tsx
import { TimezoneField } from '@ra-libs/react';

<TimezoneField source="startAtTimezone" label={'Timezone'} />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| label | false | string | | the label to display. |
| source | true | string | | the field source to retrieve its value. |
19 changes: 19 additions & 0 deletions docs/components/fields/tzdatefield.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TzDateField

TzDateField component uses ra DateField with Labeled component and timezone.

### Usage

```tsx
import { TzDateField } from '@ra-libs/react';

<TzDateField source="endAt" timezoneSource="endAtTimezone" label={'label'} useLabel />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| source | true | string | | the field source to retrieve its value. |
| timezoneSource | true | string | | the timezone field source to retrieve its value. |
19 changes: 19 additions & 0 deletions docs/components/fields/tztimefield.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TzTimeField

TzTimeField component uses ra DateField (time-only) with Labeled component and timezone.

### Usage

```tsx
import { TzTimeField } from '@ra-libs/react';

<TzTimeField source="endAt" timezoneSource="endAtTimezone" label={'label'} useLabel />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| source | true | string | | the field source to retrieve its value. |
| timezoneSource | true | string | | the timezone field source to retrieve its value. |
19 changes: 19 additions & 0 deletions docs/components/inputs/timezoneinput.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TimezoneInput

TimezoneInput component that uses mui Autocomplete with IANA list.

### Usage

```tsx
import { TimezoneInput } from '@ra-libs/react';

<TimezoneInput source="startAtTimezone" label={'Timezone'} fullWidth validate={[required()]} />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| label | false | string | | the label to display. |
| source | true | string | | the field source to retrieve its value. |
19 changes: 19 additions & 0 deletions docs/components/inputs/tzdateinput.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TzDateInput

TzDateInput component uses mui Date picker with Dayjs timezone.

### Usage

```tsx
import { TzDateInput } from '@ra-libs/react';

<TzDateInput source="endAt" timezoneSource="endAtTimezone" label={'label'} useLabel />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| source | true | string | | the field source to retrieve its value. |
| timezoneSource | true | string | | the timezone field source to retrieve its value. |
19 changes: 19 additions & 0 deletions docs/components/inputs/tztimeinput.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TzTimeInput

TzTimeInput component uses mui Time Picker with Dayjs timezone.

### Usage

```tsx
import { TzTimeInput } from '@ra-libs/react';

<TzTimeInput source="endAt" timezoneSource="endAtTimezone" label={'label'} useLabel />;
```

### Props

| Prop | Required | Type | Default | Description |
| -------------- | -------- | ------- | ------- | ---------------------------------------------------- |
| useLabel | false | boolean | false | whether to use react-admin Labeled component or not. |
| source | true | string | | the field source to retrieve its value. |
| timezoneSource | true | string | | the timezone field source to retrieve its value. |
13 changes: 12 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@
"react-hook-form": "^7.45.0",
"react-imask": "^7.0.1",
"react-number-format": "^5.2.2",
"scheduler": "^0.23.0"
"scheduler": "^0.23.0",
"timezones.json": "^1.7.1"
},
"peerDependencies": {
"react": ">=16"
Expand Down
25 changes: 25 additions & 0 deletions src/components/fields/TimezoneField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import { FunctionField, Labeled, TextFieldProps, useRecordContext, useResourceContext, useTranslate } from 'react-admin'
import timezones from 'timezones.json'

import { LabeledFieldProps } from '../../../config'

interface TimezoneFieldProps extends LabeledFieldProps<TextFieldProps> {
source: string
}

export function TimezoneField(props: TimezoneFieldProps) {
const { useLabel, source } = props

const record = useRecordContext()

const timezone = timezones.find((timezone) => timezone.utc[0] === record?.[source])

const resource = useResourceContext()
const translate = useTranslate()

const label = props.label ? props.label : translate(`resources.${resource}.fields.${source}`)

const field = <FunctionField label={label} render={() => timezone?.text} />
return useLabel ? <Labeled>{field}</Labeled> : <>{field}</>
}
39 changes: 39 additions & 0 deletions src/components/fields/TzDateField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import dayjs from 'dayjs'
import timezone from 'dayjs/plugin/timezone'
import utc from 'dayjs/plugin/utc'
import React from 'react'
import { DateField as RaDateField, DateFieldProps, Labeled, useRecordContext } from 'react-admin'

import { LabeledFieldProps } from '../../../config'

dayjs.extend(utc)
dayjs.extend(timezone)

interface TzDateFieldProps extends LabeledFieldProps<DateFieldProps> {
timezoneSource: string
source: string
}

export function TzDateField(props: TzDateFieldProps) {
const { useLabel, timezoneSource, ...rest } = props

const record = useRecordContext()
const timezone = record?.[timezoneSource]
const date = record?.[rest.source]
const utcDate = dayjs(date)

const field = (
<RaDateField
{...rest}
showDate
showTime={false}
transform={() => {
return utcDate.toDate()
}}
options={{
timeZone: timezone,
}}
/>
)
return useLabel ? <Labeled>{field}</Labeled> : <>{field}</>
}
38 changes: 38 additions & 0 deletions src/components/fields/TzTimeField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import dayjs from 'dayjs'
import timezone from 'dayjs/plugin/timezone'
import utc from 'dayjs/plugin/utc'
import React from 'react'
import { DateField as RaDateField, DateFieldProps, Labeled, useRecordContext } from 'react-admin'

import { LabeledFieldProps } from '../../../config'

dayjs.extend(utc)
dayjs.extend(timezone)

interface TzTimeFieldProps extends LabeledFieldProps<DateFieldProps> {
timezoneSource: string
source: string
}

export function TzTimeField(props: TzTimeFieldProps) {
const { useLabel, timezoneSource, ...rest } = props
const record = useRecordContext()
const timezone = record?.[timezoneSource]
const date = record?.[rest.source]
const utcDate = dayjs(date)

const field = (
<RaDateField
{...rest}
showDate={false}
showTime
transform={() => utcDate.toDate()}
options={{
hour: '2-digit',
minute: '2-digit',
timeZone: timezone,
}}
/>
)
return useLabel ? <Labeled>{field}</Labeled> : <>{field}</>
}
3 changes: 3 additions & 0 deletions src/components/fields/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ export * from './CountryField'
export * from './TimelineArrayField'
export * from './TimeField'
export * from './PhoneField'
export * from './TzDateField'
export * from './TzTimeField'
export * from './TimezoneField'
Loading

0 comments on commit f71db9b

Please sign in to comment.