Created section to set default date interval for visits

This commit is contained in:
Alejandro Celaya
2021-03-06 16:54:43 +01:00
parent d3f9650e82
commit fee62484b5
12 changed files with 170 additions and 42 deletions

View File

@@ -1,22 +1,29 @@
import { FC } from 'react';
import { FC, ReactNode } from 'react';
import { Row } from 'reactstrap';
import NoMenuLayout from '../common/NoMenuLayout';
const Settings = (RealTimeUpdates: FC, ShortUrlCreation: FC, UserInterface: FC) => () => (
const SettingsSections: FC<{ items: ReactNode[][] }> = ({ items }) => (
<>
{items.map((child, index) => (
<Row key={index}>
{child.map((subChild, subIndex) => (
<div key={subIndex} className="col-lg-6">
<div className="mb-3 mb-md-4">{subChild}</div>
</div>
))}
</Row>
))}
</>
);
const Settings = (RealTimeUpdates: FC, ShortUrlCreation: FC, UserInterface: FC, Visits: FC) => () => (
<NoMenuLayout>
<Row>
<div className="col-lg-6">
<div className="mb-3 mb-md-4">
<UserInterface />
</div>
<div className="mb-3 mb-md-4">
<ShortUrlCreation />
</div>
</div>
<div className="col-lg-6">
<RealTimeUpdates />
</div>
</Row>
<SettingsSections
items={[
[ <UserInterface />, <ShortUrlCreation /> ], // eslint-disable-line react/jsx-key
[ <Visits />, <RealTimeUpdates /> ], // eslint-disable-line react/jsx-key
]}
/>
</NoMenuLayout>
);

22
src/settings/Visits.tsx Normal file
View File

@@ -0,0 +1,22 @@
import { FormGroup } from 'reactstrap';
import { FC } from 'react';
import { SimpleCard } from '../utils/SimpleCard';
import { DateIntervalSelector } from '../utils/dates/DateIntervalSelector';
import { Settings, VisitsSettings } from './reducers/settings';
interface VisitsProps {
settings: Settings;
setVisitsSettings: (settings: VisitsSettings) => void;
}
export const Visits: FC<VisitsProps> = ({ settings, setVisitsSettings }) => (
<SimpleCard title="Visits">
<FormGroup className="mb-0">
<label>Default interval to load on visits sections:</label>
<DateIntervalSelector
active={settings.visits?.defaultInterval ?? 'last30Days'}
onChange={(defaultInterval) => setVisitsSettings({ defaultInterval })}
/>
</FormGroup>
</SimpleCard>
);

View File

@@ -78,3 +78,8 @@ export const setUiSettings = (settings: UiSettings): PartialSettingsAction => ({
type: SET_SETTINGS,
ui: settings,
});
export const setVisitsSettings = (settings: VisitsSettings): PartialSettingsAction => ({
type: SET_SETTINGS,
visits: settings,
});

View File

@@ -5,16 +5,18 @@ import {
setRealTimeUpdatesInterval,
setShortUrlCreationSettings,
setUiSettings,
setVisitsSettings,
toggleRealTimeUpdates,
} from '../reducers/settings';
import { ConnectDecorator } from '../../container/types';
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
import { ShortUrlCreation } from '../ShortUrlCreation';
import { UserInterface } from '../UserInterface';
import { Visits } from '../Visits';
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
// Components
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates', 'ShortUrlCreation', 'UserInterface');
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates', 'ShortUrlCreation', 'UserInterface', 'Visits');
bottle.decorator('Settings', withoutSelectedServer);
bottle.decorator('Settings', connect(null, [ 'resetSelectedServer' ]));
@@ -30,11 +32,15 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
bottle.serviceFactory('UserInterface', () => UserInterface);
bottle.decorator('UserInterface', connect([ 'settings' ], [ 'setUiSettings' ]));
bottle.serviceFactory('Visits', () => Visits);
bottle.decorator('Visits', connect([ 'settings' ], [ 'setVisitsSettings' ]));
// Actions
bottle.serviceFactory('toggleRealTimeUpdates', () => toggleRealTimeUpdates);
bottle.serviceFactory('setRealTimeUpdatesInterval', () => setRealTimeUpdatesInterval);
bottle.serviceFactory('setShortUrlCreationSettings', () => setShortUrlCreationSettings);
bottle.serviceFactory('setUiSettings', () => setUiSettings);
bottle.serviceFactory('setVisitsSettings', () => setVisitsSettings);
};
export default provideServices;

View File

@@ -0,0 +1,20 @@
import { DropdownItem } from 'reactstrap';
import { FC } from 'react';
import { DATE_INTERVALS, DateInterval, rangeOrIntervalToString } from './types';
export interface DateIntervalDropdownProps {
active?: DateInterval;
onChange: (interval: DateInterval) => void;
}
export const DateIntervalDropdownItems: FC<DateIntervalDropdownProps> = ({ active, onChange }) => (
<>
{DATE_INTERVALS.map(
(interval) => (
<DropdownItem key={interval} active={active === interval} onClick={() => onChange(interval)}>
{rangeOrIntervalToString(interval)}
</DropdownItem>
),
)}
</>
);

View File

@@ -0,0 +1,10 @@
import { FC } from 'react';
import { DropdownBtn } from '../DropdownBtn';
import { rangeOrIntervalToString } from './types';
import { DateIntervalDropdownItems, DateIntervalDropdownProps } from './DateIntervalDropdownItems';
export const DateIntervalSelector: FC<DateIntervalDropdownProps> = ({ onChange, active }) => (
<DropdownBtn text={rangeOrIntervalToString(active) ?? ''}>
<DateIntervalDropdownItems active={active} onChange={onChange} />
</DropdownBtn>
);

View File

@@ -10,6 +10,7 @@ import {
rangeIsInterval,
} from './types';
import DateRangeRow from './DateRangeRow';
import { DateIntervalDropdownItems } from './DateIntervalDropdownItems';
export interface DateRangeSelectorProps {
initialDateRange?: DateInterval | DateRange;
@@ -47,13 +48,7 @@ export const DateRangeSelector = (
{defaultText}
</DropdownItem>
<DropdownItem divider />
{([ 'today', 'yesterday', 'last7Days', 'last30Days', 'last90Days', 'last180days', 'last365Days' ] as DateInterval[]).map(
(interval) => (
<DropdownItem key={interval} active={activeInterval === interval} onClick={updateInterval(interval)}>
{rangeOrIntervalToString(interval)}
</DropdownItem>
),
)}
<DateIntervalDropdownItems active={activeInterval} onChange={(interval) => updateInterval(interval)()} />
<DropdownItem divider />
<DropdownItem header>Custom:</DropdownItem>
<DropdownItem text>

View File

@@ -24,6 +24,8 @@ const INTERVAL_TO_STRING_MAP: Record<DateInterval, string> = {
last365Days: 'Last 365 days',
};
export const DATE_INTERVALS: DateInterval[] = Object.keys(INTERVAL_TO_STRING_MAP) as DateInterval[];
const dateRangeToString = (range?: DateRange): string | undefined => {
if (!range || dateRangeIsEmpty(range)) {
return undefined;