date-fns#isBefore TypeScript Examples
The following examples show how to use
date-fns#isBefore.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: schedule.ts From tempomat with MIT License | 6 votes |
export function createScheduleDetails(
worklogsResults: WorklogEntity[],
scheduleResults: ScheduleEntity[],
formattedSelectedDate: string,
accountId?: string
): ScheduleDetails {
const now = time.now()
const formattedNowDate = format(now, DATE_FORMAT)
const userAccountWorklogs = worklogsResults
.filter((e: WorklogEntity) => e.author.accountId === accountId)
const dayWorklogResults = userAccountWorklogs
.filter((e: WorklogEntity) => e.startDate === formattedSelectedDate && e.author.accountId === accountId)
const dayScheduleResults = scheduleResults.filter((e: ScheduleEntity) => e.date === formattedSelectedDate)
const daysToTodayScheduleResults = scheduleResults
.filter((e: ScheduleEntity) => e.date === formattedNowDate || isBefore(fnsParse(e.date, DATE_FORMAT, new Date()), now))
const monthRequiredSeconds = _.sumBy(scheduleResults, (r) => r.requiredSeconds)
const monthLoggedSeconds = _.sumBy(userAccountWorklogs, (r) => r.timeSpentSeconds)
const monthCurrentPeriodSeconds = monthLoggedSeconds - _.sumBy(daysToTodayScheduleResults, (r) => r.requiredSeconds)
const dayRequiredSeconds = _.sumBy(dayScheduleResults, (r) => r.requiredSeconds)
const dayLoggedSeconds = _.sumBy(dayWorklogResults, (r) => r.timeSpentSeconds)
return {
monthRequiredDuration: timeParser.toDuration(monthRequiredSeconds),
monthLoggedDuration: timeParser.toDuration(monthLoggedSeconds),
monthCurrentPeriodDuration: timeParser.toDuration(monthCurrentPeriodSeconds, true),
dayRequiredDuration: timeParser.toDuration(dayRequiredSeconds),
dayLoggedDuration: timeParser.toDuration(dayLoggedSeconds)
}
}
Example #2
Source File: dategrid.ts From calendar-hack with MIT License | 6 votes |
setEvent(date: Date, event: T | undefined) {
const k = key(date);
if (event) {
this._events.set(k, event);
// min/max/first/last/weekCount maintenance
if (!this._max || isAfter(date, this._max))
this._max = date;
this._last = startOfDay(endOfWeek(this._max, { weekStartsOn: 1 }))
if (!this._min || isBefore(date, this._min))
this._min = date;
this._first = startOfWeek(this._min, { weekStartsOn: 1 })
this._weekCount = differenceInWeeks(startOfDay(addDays(this._last, 1)), this._first);
} else {
this._events.delete(k);
}
}
Example #3
Source File: DayPicker.tsx From symphony-ui-toolkit with Apache License 2.0 | 6 votes |
arrowNavigation(date: Date, nextDate: Date) {
const delta = differenceInCalendarMonths(nextDate, date);
const action = isBefore(date, nextDate) ? 'next' : 'previous';
if (delta !== 0) {
this.setState({ currentMonth: nextDate }, () =>
this.focusOnlyEnabledCell(nextDate, action, null, false)
);
} else {
this.focusOnlyEnabledCell(nextDate, action, null);
}
}
Example #4
Source File: sleep-data-helper.ts From nyxo-app with GNU General Public License v3.0 | 6 votes |
// Find the starting time of the night
export function findStartTime(nights: Night[], value: Value): string {
const nightStartTime = nights
?.filter((n: Night) => n.value === value)
.reduce((previousValue: Night, currentValue: Night) =>
isBefore(
new Date(previousValue.startDate),
new Date(currentValue.startDate)
)
? previousValue
: currentValue
)
return new Date(nightStartTime.startDate).toISOString()
}
Example #5
Source File: dateUtils.ts From ant-extensions with MIT License | 6 votes |
makeSuperDate = (start?: DateValue, end?: DateValue) => {
const startParsed = parseDate(start);
const endParsed = parseDate(end);
if (start && end && start && end && startParsed && endParsed) {
return isBefore(startParsed, endParsed) ? `${start}|${end}` : `${end}|${start}`;
} else if (start && !end && start) {
return start.includes("-") ? `${start}|${DateParts.NOW}` : `${DateParts.NOW}|${start}`;
}
return undefined;
}
Example #6
Source File: claimable-balances.service.ts From xBull-Wallet with GNU Affero General Public License v3.0 | 6 votes |
canBeClaimed(predicate: Horizon.Predicate): boolean {
let canClaim = false;
// TODO: later when there is proper typing from the SDK, update this
if ((predicate as any).unconditional === true) {
canClaim = true;
}
if (typeof predicate.abs_before !== 'undefined') {
canClaim = isBefore(new Date(), new Date(predicate.abs_before));
}
if (typeof predicate.rel_before !== 'undefined') {
canClaim = isAfter(new Date(), new Date(predicate.rel_before));
}
if (typeof predicate.not !== 'undefined') {
canClaim = !this.canBeClaimed(predicate.not);
}
if (typeof predicate.and !== 'undefined') {
canClaim = predicate.and.every(p => this.canBeClaimed(p));
}
if (typeof predicate.or !== 'undefined') {
canClaim = !!predicate.or.find(p => this.canBeClaimed(p));
}
return canClaim;
}
Example #7
Source File: coaching.ts From nyxo-app with GNU General Public License v3.0 | 6 votes |
canEndCoaching = (
startDate: string | undefined | null,
duration: number
): boolean => {
if (startDate) {
return isBefore(
addDays(startOfDay(new Date(startDate)), duration),
startOfDay(new Date())
)
}
return false
}
Example #8
Source File: DatePicker.stories.tsx From gio-design with Apache License 2.0 | 5 votes |
StaticDisabledDate.args = {
disabledDate: (date: Date) => isBefore(startOfToday(), date),
};
Example #9
Source File: db.ts From command-bot with Apache License 2.0 | 5 votes |
getSortedTasks = async (
{ taskDb: { db }, logger }: Pick<Context, "taskDb" | "logger">,
{
onlyNotAlive,
}: {
onlyNotAlive?: boolean
} = {},
) => {
type Item = {
id: DbKey
queuedDate: Date
task: Task
}
const items = await new Promise<Item[]>((resolve, reject) => {
const databaseItems: Item[] = []
db.createReadStream()
.on(
"data",
({
key: rawKey,
value: rawValue,
}: {
key: ToString
value: ToString
}) => {
try {
const key = rawKey.toString()
const value = rawValue.toString()
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const task: Task = JSON.parse(value)
if (!onlyNotAlive || !queuedTasks.has(task.id)) {
const queuedDate = parseTaskQueuedDate(task.queuedDate)
if (isValid(queuedDate)) {
databaseItems.push({ id: key, queuedDate, task })
} else {
logger.error(
{ key, value },
"Found key with invalid date in the database",
)
void db.del(key)
}
}
} catch (error) {
reject(error)
}
},
)
.on("error", (error) => {
reject(error)
})
.on("end", () => {
resolve(databaseItems)
})
})
items.sort(
(
{ queuedDate: dateA, task: taskA },
{ queuedDate: dateB, task: taskB },
) => {
if (isBefore(dateA, dateB)) {
return -1
} else if (isBefore(dateB, dateA)) {
return 1
} else if (taskA.id < taskB.id) {
return -1
} else if (taskB.id < taskA.id) {
return 1
}
return 0
},
)
return items
}
Example #10
Source File: index.ts From MDDL with MIT License | 5 votes |
@Action({ rawError: true })
async createCollection(payload: CollectionCreate): Promise<Collection> {
if (!this.ownerId) return Promise.reject(new Error('UserID not set'))
const { data } = await api.user.addUserCollection(this.ownerId, payload)
const documents = await this.getDocuments()
const dates = documents.map((d) => new Date(d.createdDate))
const oldest = dates.reduce(
(oldest, current) => (isBefore(current, oldest) ? current : oldest),
dates[0],
)
const newest = dates.reduce(
(newest, current) => (isBefore(current, newest) ? newest : current),
dates[0],
)
const currentDate = Date.now()
const daysSinceOldest = differenceInDays(currentDate, oldest)
const daysSinceNewest = differenceInDays(currentDate, newest)
this.$ga.event({
eventCategory: 'collection_shared',
eventAction: 'number_of_recipients',
eventLabel: UserRole[this._role!],
eventValue: payload.individualEmailAddresses.length,
})
this.$ga.event({
eventCategory: 'collection_shared',
eventAction: 'number_of_documents',
eventLabel: UserRole[this._role!],
eventValue: payload.documentIds.length,
})
this.$ga.event({
eventCategory: 'collection_shared',
eventAction: 'days_since_oldest_document',
eventLabel: UserRole[this._role!],
eventValue: daysSinceOldest,
})
this.$ga.event({
eventCategory: 'collection_shared',
eventAction: 'days_since_newest_document',
eventLabel: UserRole[this._role!],
eventValue: daysSinceNewest,
})
return data
}
Example #11
Source File: CreateAppointmentService.ts From GoBarber with MIT License | 5 votes |
public async execute({
provider_id,
user_id,
date,
}: IRequest): Promise<Appointment> {
const appointmentDate = startOfHour(date);
if (isBefore(appointmentDate, Date.now())) {
throw new AppError("You can't book appointments in past dates");
}
if (provider_id === user_id) {
throw new AppError("You can't book appointments with yourself");
}
if (getHours(appointmentDate) < 8 || getHours(appointmentDate) > 17) {
throw new AppError("You can't book appointments outside commercial time");
}
const findAppointmentInSameDate = await this.appointmentsRepository.findByDate(
appointmentDate,
provider_id,
);
if (findAppointmentInSameDate) {
throw new AppError('This appointment is already booked');
}
const appointment = await this.appointmentsRepository.create({
provider_id,
user_id,
date: appointmentDate,
});
const dateFormatted = format(appointmentDate, "dd/MM/yyyy 'às' HH:mm'h'");
await this.notificationsRepository.create({
recipient_id: provider_id,
content: `Novo agendamento para ${dateFormatted}`,
});
await this.cacheProvider.invalidate(
`provider-appointments:${provider_id}:${format(
appointmentDate,
'd-M-yyyy',
)}`,
);
return appointment;
}
Example #12
Source File: CreateAppointmentService.ts From gobarber-project with MIT License | 5 votes |
public async execute({
provider_id,
user_id,
date,
}: IRequest): Promise<Appointment> {
const appointmentDate = startOfHour(date);
if (isBefore(appointmentDate, Date.now())) {
throw new AppError("You can't create an appointment on a past date");
}
if (user_id === provider_id) {
throw new AppError("You can't create an appointment with yourself");
}
if (getHours(appointmentDate) < 8 || getHours(appointmentDate) > 17) {
throw new AppError(
'You can only create appointments between 8am and 5pm',
);
}
const findAppoitmentInSameDate = await this.appointmentsRepository.findByDate(
appointmentDate,
provider_id,
);
if (findAppoitmentInSameDate) {
throw new AppError('This appointment is already booked');
}
const appointment = await this.appointmentsRepository.create({
provider_id,
user_id,
date: appointmentDate,
});
const dateFormatted = format(appointmentDate, "dd/MM/yyyy 'às' HH:mm'h'");
await this.notificationsRepository.create({
recipient_id: provider_id,
content: `Novo agendamento para dia ${dateFormatted}`,
});
await this.cacheProvider.invalidate(
`provider-appointments:${provider_id}:${format(
appointmentDate,
'yyyy-M-d',
)}`,
);
return appointment;
}
Example #13
Source File: validator.ts From elements with MIT License | 5 votes |
private validateMaxSingle = (value: string): boolean => {
const parsedDate: Date = this.parseDate(value);
return (
isEqual(parsedDate, this._maxDate) || isBefore(parsedDate, this._maxDate)
);
};
Example #14
Source File: matchDayUtils.tsx From symphony-ui-toolkit with Apache License 2.0 | 5 votes |
function isDayBefore(day1: Date, day2: Date): boolean {
return isBefore(day1, day2) && !isSameDay(day1, day2);
}
Example #15
Source File: pause.tsx From protect-scotland with Apache License 2.0 | 5 votes |
Pause: FC = () => {
const navigation = useNavigation();
const {t} = useTranslation();
const {pause} = useExposure();
const [selectedInterval, setSelectedInterval] = useState<Date>(
getClosestInterval(15)
);
const [selected, setSelected] = useState<boolean>(false);
const [show, setShow] = useState(false);
const {setReminder} = useReminder();
return (
<>
<View style={styles.header}>
<ModalClose onPress={() => navigation.goBack()} />
</View>
<ScrollView contentContainerStyle={styles.contentContainerStyle}>
<Text variant="h3" color="darkGrey">
{t('pause:title')}
</Text>
<Spacing s={24} />
<Text color="darkGrey">{t('pause:body')}</Text>
<Spacing s={24} />
<Markdown accessibleLink={t('links:o')}>
{t('pause:label', {link: t('links:o')})}
</Markdown>
<Spacing s={24} />
<Button
type="secondary"
variant="green"
rounded
buttonStyle={styles.smallButton}
onPress={() => setShow(true)}>
{!selected ? (
t('pause:setTimeButton')
) : (
<>
{format(selectedInterval, 'HH:mm')}{' '}
{isBefore(selectedInterval, new Date())
? t('common:tomorrow')
: t('common:today')}
</>
)}
</Button>
<DateTimePickerModal
isVisible={show}
mode="time"
display="spinner"
minuteInterval={15}
date={selectedInterval}
onConfirm={(e) => {
setShow(false);
setSelectedInterval(e);
setSelected(true);
}}
onCancel={() => setShow(false)}
headerTextIOS={t('pause:modalHeader')}
/>
<Spacing s={18} />
<Button
type="primary"
variant="green"
rounded
onPress={() => {
pause();
setReminder(selectedInterval);
navigation.goBack();
}}>
{t('pause:button')}
</Button>
</ScrollView>
</>
);
}
Example #16
Source File: ListProviderAppointmentsService.ts From hotseat-api with MIT License | 5 votes |
async execute({
day,
year,
month,
provider_id,
}: IRequest): Promise<IResponse[]> {
const appointmentsListCacheKey = getProviderAppointmentsListCacheKey(
provider_id,
new Date(year, parseMonthToJSMonth(month), day),
);
let appointments = await this.cacheProvider.get<Appointment[]>(
appointmentsListCacheKey,
);
if (!appointments) {
appointments = await this.appointmentsRepository.findByDayFromProvider({
day,
year,
month,
provider_id,
});
await this.cacheProvider.save<Appointment[]>(
appointmentsListCacheKey,
classToClass(appointments),
);
}
const listAppointments = appointments.map(appointment => {
const currentDate = new Date(Date.now());
const parseCachedDate =
typeof appointment.date === 'string'
? parseISO(appointment.date)
: appointment.date;
return {
...appointment,
isPast: isBefore(parseCachedDate, currentDate),
};
});
return listAppointments;
}
Example #17
Source File: CreateAppointmentService.ts From gobarber-api with MIT License | 5 votes |
public async execute({
date,
provider_id,
user_id,
}: IRequest): Promise<Appointment> {
const appointmentDate = startOfHour(date);
if (isBefore(appointmentDate, Date.now())) {
throw new AppError("You cant't create an appointment on past date");
}
if (user_id === provider_id) {
throw new AppError("You can't create an appointment with yourself");
}
if (getHours(appointmentDate) < 8 || getHours(appointmentDate) > 17) {
throw new AppError(
'You can only create appointments between 8am and 5pm',
);
}
const findAppointmentInSameDate = await this.appointmentsRepository.findByDate(
{
date: appointmentDate,
provider_id,
},
);
if (findAppointmentInSameDate) {
throw new AppError('This appointment is already booked');
}
const appointment = await this.appointmentsRepository.create({
user_id,
provider_id,
date: appointmentDate,
});
const dateFormated = format(appointmentDate, "dd/MM/yyyy 'às' HH:mm'h'");
await this.notificationsRepository.create({
recipient_id: provider_id,
content: `Novo agendamento para dia ${dateFormated}.`,
});
await this.cacheProvider.invalidate(
`provider-appointments:${provider_id}:${format(
appointmentDate,
'yyyy-M-d',
)}`,
);
return appointment;
}
Example #18
Source File: BudgetTransaction.ts From cashcash-desktop with MIT License | 4 votes |
actions = {
async initWipTransaction(
{ commit }: Vuex.ActionContext<IBudgetTransactionState, any>,
obj: { transactionId: string; duplicate: boolean },
) {
let flatTransaction;
if (obj.transactionId === 'new') {
flatTransaction = new FlatCashTransaction({ description: 'NO DESCRIPTION' });
} else {
const service = Container.get(CashBudgetTransactionService);
flatTransaction = await service.getFlat(obj.transactionId);
}
commit('updateField', { path: 'wipTransaction', value: flatTransaction });
},
async removeWipTransaction({ commit }: Vuex.ActionContext<IBudgetTransactionState, any>) {
commit('updateField', { path: 'wipTransaction', value: null });
},
async saveTransaction(
{ dispatch, commit }: Vuex.ActionContext<IBudgetTransactionState, any>,
wipTransaction: FlatCashTransaction,
) {
const service = Container.get(CashBudgetTransactionService);
await service.save(wipTransaction);
Notification.success({
title: i18n.t('Budget entry saved').toString(),
message: '',
});
commit('updateField', { path: 'wipTransaction', value: null });
await dispatch('PermanentData/fillBudgetSplit', {}, { root: true });
},
async saveTransactionList(
{ dispatch, commit }: Vuex.ActionContext<IBudgetTransactionState, any>,
wipTransactionList: FlatCashTransaction[],
) {
const service = Container.get(CashBudgetTransactionService);
await service.saveList(wipTransactionList);
Notification.success({
title: i18n
.t('{total} budget entries saved', {
total: wipTransactionList.filter((item) => !item.doNotImport).length,
})
.toString(),
message: '',
});
commit('updateField', { path: 'wipTransaction', value: null });
await dispatch('PermanentData/fillBudgetSplit', {}, { root: true });
},
async deleteTransaction(
{ dispatch }: Vuex.ActionContext<IBudgetTransactionState, any>,
transactionId: string,
) {
const service = Container.get(CashBudgetTransactionService);
await service.delete(transactionId);
Notification.success({
title: i18n.t('Budget entry deleted').toString(),
message: '',
});
await dispatch('PermanentData/fillBudgetSplit', {}, { root: true });
},
async deleteTransactionList(
{ dispatch }: Vuex.ActionContext<IBudgetTransactionState, any>,
transactionIdList: string[],
) {
if (transactionIdList.length === 1) {
await dispatch('deleteTransaction', transactionIdList[0]);
} else {
const service = Container.get(CashBudgetTransactionService);
await service.deleteList(transactionIdList);
Notification.success({
title: i18n
.t('{total} transactions deleted', { total: transactionIdList.length })
.toString(),
message: '',
});
await dispatch('PermanentData/fillBudgetSplit', {}, { root: true });
}
},
async updateBudgetDate(
{ commit }: Vuex.ActionContext<IBudgetTransactionState, any>,
budgetDate: Date,
) {
commit('updateField', { path: 'budgetDate', value: budgetDate });
},
async adjustBudgetDateIfNeeded({
commit,
state,
rootState,
}: Vuex.ActionContext<IBudgetTransactionState, any>) {
const parameters = rootState.TimeFrameData.parameters;
const transactionDateFrom = parameters.transactionDateFrom;
const transactionDateTo = parameters.transactionDateTo;
if (
isAfter(state.budgetDate, transactionDateTo) ||
isBefore(state.budgetDate, transactionDateFrom)
) {
const newBudgetDate = transactionDateTo;
commit('updateField', { path: 'budgetDate', value: newBudgetDate });
}
},
async updateContextAccount(
{ commit, rootState }: Vuex.ActionContext<IBudgetTransactionState, any>,
account: CashAccount,
) {
if (!account) {
account = rootState.PermanentData.accountTree.find((item) => item.code === 'ASS');
}
commit('updateField', { path: 'contextAccount', value: account });
},
async updateIsPageOpen(
{ commit }: Vuex.ActionContext<IBudgetTransactionState, any>,
isPageOpen: boolean,
) {
commit('updateField', { path: 'isPageOpen', value: isPageOpen });
},
}
Example #19
Source File: DateTimeRangePicker.tsx From UUI with MIT License | 4 votes |
DateTimeRangePicker = UUIFunctionComponent({
name: 'DateTimeRangePicker',
nodes: {
Root: 'div',
ConnectIcon: Icons.ArrowRight,
CalendarIcon: Icons.Calendar,
Popover: UUIPopover,
TextField: UUITextField,
Activator: 'div',
Container: 'div',
Toolbar: 'div',
Main: 'div',
StartSection: 'div',
EndSection: 'div',
Section: 'div',
PickerButtons: UUIPickerButtons,
YearMonthSelect: UUIYearMonthSelect,
DateSelect: UUIDateSelect,
TimeSelect: UUITimeSelect,
DateTimeShortcut: UUIDateTimeShortcut,
},
propTypes: DateTimeRangePickerPropTypes,
}, (props: DateTimeRangePickerFeatureProps, { nodes }) => {
const {
Root, ConnectIcon, CalendarIcon, Popover, TextField,
Activator, Container, Main, StartSection, EndSection, Section,
YearMonthSelect, DateSelect, TimeSelect, DateTimeShortcut, PickerButtons,
} = nodes
const startTimeSelectRef = useRef<any | null>(null)
const endTimeSelectRef = useRef<any | null>(null)
const startInputRef = useRef<HTMLInputElement | null>(null)
const endInputRef = useRef<HTMLInputElement | null>(null)
const [active, setActive] = useState(false)
const [whichFocusing, setWhichFocusing] = useState<'start' | 'end'>()
const [hoverDate, setHoverDate] = useState<Date>()
const initialInnerValue = useMemo(() => {
if (props.value === null) {
return {
startDate: null,
endDate: null,
startInput: '',
endInput: '',
startYearMonth: startOfMonth(new Date),
endYearMonth: add(startOfMonth(new Date), { months: 1 }),
}
}
return {
startDate: props.value[0],
endDate: props.value[1],
startInput: formatDateTime(props.value[0]),
endInput: formatDateTime(props.value[1]),
startYearMonth: startOfMonth(props.value[0]),
endYearMonth: isSameMonth(props.value[0], props.value[1]) ? add(startOfMonth(props.value[1]), { months: 1 }) : props.value[1],
}
}, [props.value])
const [innerValue, setInnerValue, resetInnerValue] = usePendingValue<DateTimeRangePickerInnerValue>(initialInnerValue, (value) => {
if (value.startDate && value.endDate) {
handleValueOnChange([value.startDate, value.endDate])
closePopover()
}
}, { resetWhenInitialValueChanged: true })
const selectedDates = useMemo(() => {
return compact([innerValue.startDate, innerValue.endDate])
}, [innerValue.endDate, innerValue.startDate])
const timeSelectScrollToValue = useCallback((type: 'start' | 'end', value: Date, animate?: boolean) => {
if (type === 'start' && startTimeSelectRef.current) {
startTimeSelectRef.current.scrollToValue(value, animate)
}
if (type === 'end' && endTimeSelectRef.current) {
endTimeSelectRef.current.scrollToValue(value, animate)
}
}, [])
const openPopover = useCallback(() => { setActive(true) }, [])
const closePopover = useCallback(() => { setActive(false) }, [])
const handleValueOnChange = useCallback((value: DateTimeRangePickerValue | null) => {
const sortedValue = value?.sort((i, j) => Number(i) - Number(j)) || null
props.onChange(sortedValue)
}, [props])
/**
*
*/
const handleInputOnSubmit = useCallback((type: 'start' | 'end') => {
if (innerValue.startDate && innerValue.endDate) {
const originalInput = formatDateTime(type === 'start' ? innerValue.startDate : innerValue.endDate)
const input = type === 'start' ? innerValue.startInput : innerValue.endInput
if (originalInput === input) return;
try {
if (input === '') {
handleValueOnChange(null)
} else {
const result = tryParseDateTimeFromString(input)
handleValueOnChange(type === 'start' ? [result, innerValue.endDate] : [innerValue.startDate, result])
}
} catch {
resetInnerValue()
}
}
}, [handleValueOnChange, innerValue.endInput, innerValue.endDate, innerValue.startInput, innerValue.startDate, resetInnerValue])
/**
* handle user change year or month in YearMonthSelect.
*/
const handleStartYearMonthSelect = useCallback((value: Date) => {
setInnerValue((oldValue) => {
const startYearMonthDate = value
let endYearMonthDate = oldValue.endYearMonth
if (!isBefore(startYearMonthDate, endYearMonthDate)) {
endYearMonthDate = add(startYearMonthDate, { months: 1 })
}
return {
...oldValue,
startYearMonth: startYearMonthDate,
endYearMonth: endYearMonthDate,
}
})
}, [setInnerValue])
const handleEndYearMonthSelect = useCallback((value: Date) => {
setInnerValue((oldValue) => {
const endYearMonthDate = value
let startYearMonthDate = oldValue.startYearMonth
if (!isAfter(endYearMonthDate, startYearMonthDate)) {
startYearMonthDate = add(endYearMonthDate, { months: -1 })
}
return {
...oldValue,
startYearMonth: startYearMonthDate,
endYearMonth: endYearMonthDate,
}
})
}, [setInnerValue])
/**
* handle user select date in DateSelect.
*/
const handleDateSelect = useCallback((value: Date) => {
let newStartValue = innerValue.startDate
let newEndValue = innerValue.endDate
if (
(newStartValue !== null && newEndValue !== null) ||
(newStartValue === null && newEndValue === null)
) {
if (whichFocusing === 'end') {
newStartValue = null
newEndValue = value
} else {
newStartValue = value
newEndValue = null
}
} else {
if (newStartValue === null) newStartValue = value
if (newEndValue === null) newEndValue = value
if (isAfter(newStartValue, newEndValue)) {
const tmp = new Date(newStartValue)
newStartValue = new Date(newEndValue)
newEndValue = tmp
}
}
setInnerValue((oldValue) => {
return {
...oldValue,
startDate: newStartValue,
startInput: formatDateTime(newStartValue),
endDate: newEndValue,
endInput: formatDateTime(newEndValue),
}
})
}, [innerValue.endDate, innerValue.startDate, setInnerValue, whichFocusing])
/**
* handle user select date in TimeSelect.
*/
const handleTimeSelect = useCallback((type: 'start' | 'end') => {
return (value: Date) => {
setInnerValue((oldValue) => {
const oldDate = type === 'start' ? oldValue.startDate : oldValue.endDate
const newDate = set(oldDate || getZeroDate(), {
hours: value.getHours(),
minutes: value.getMinutes(),
seconds: value.getSeconds(),
})
const newInput = formatDateTime(newDate)
return {
...oldValue,
...(type === 'start' ? {
startDate: newDate,
startInput: newInput,
} : {}),
...(type === 'end' ? {
endDate: newDate,
endInput: newInput,
} : {}),
}
})
}
}, [setInnerValue])
return (
<Root>
<Popover
placement={'bottom-start'}
active={active}
onClickAway={() => {
resetInnerValue();
timeSelectScrollToValue('start', props.value ? props.value[0] : getZeroDate(), false)
timeSelectScrollToValue('end', props.value ? props.value[1] : getZeroDate(), false)
setTimeout(() => { closePopover() }, 10)
}}
activator={
<Activator
onClick={() => {
openPopover()
setTimeout(() => {
const focusedElement = ReactHelper.document?.activeElement
if (startInputRef.current === focusedElement || endInputRef.current === focusedElement) return;
if (startInputRef.current) {
startInputRef.current.focus()
}
}, 0)
}}
>
<TextField
placeholder={props.startPlaceholder}
value={innerValue.startInput}
onChange={(value) => { setInnerValue((oldValue) => ({ ...oldValue, startInput: value })) }}
customize={{
Input: {
ref: startInputRef,
onFocus: () => {
setWhichFocusing('start')
},
onBlur: () => {
setWhichFocusing(undefined)
handleInputOnSubmit('start')
},
onKeyDown: (event) => {
if (event.key === 'Enter') {
handleInputOnSubmit('start')
}
}
}
}}
/>
<ConnectIcon />
<TextField
placeholder={props.endPlaceholder}
value={innerValue.endInput}
onChange={(value) => { setInnerValue((oldValue) => ({ ...oldValue, endInput: value })) }}
customize={{
Input: {
ref: endInputRef,
onFocus: () => {
setWhichFocusing('end')
},
onBlur: () => {
setWhichFocusing(undefined)
handleInputOnSubmit('end')
},
onKeyDown: (event) => {
if (event.key === 'Enter') {
handleInputOnSubmit('end')
}
}
}
}}
/>
<CalendarIcon />
</Activator>
}
>
<Container>
<Main tabIndex={-1}>
{props.shortcuts && (
<DateTimeShortcut
options={props.shortcuts}
onSelect={(value) => {
handleValueOnChange(value)
timeSelectScrollToValue('start', value ? value[0] : getZeroDate(), false)
timeSelectScrollToValue('end', value ? value[1] : getZeroDate(), false)
closePopover()
}}
/>
)}
<StartSection>
<YearMonthSelect
value={innerValue.startYearMonth}
onChange={handleStartYearMonthSelect}
/>
<Section>
<DateSelect
yearMonth={innerValue.startYearMonth}
selectedDates={selectedDates}
onSelect={handleDateSelect}
hoverDate={hoverDate}
onHoverDateChange={(date) => { setHoverDate(date) }}
/>
<TimeSelect
ref={startTimeSelectRef}
value={innerValue.startDate || getZeroDate()}
onChange={handleTimeSelect('start')}
/>
</Section>
</StartSection>
<EndSection>
<YearMonthSelect
value={innerValue.endYearMonth}
onChange={handleEndYearMonthSelect}
/>
<Section>
<DateSelect
yearMonth={innerValue.endYearMonth}
selectedDates={selectedDates}
onSelect={handleDateSelect}
hoverDate={hoverDate}
onHoverDateChange={(date) => { setHoverDate(date) }}
/>
<TimeSelect
ref={endTimeSelectRef}
value={innerValue.endDate || getZeroDate()}
onChange={handleTimeSelect('end')}
/>
</Section>
</EndSection>
</Main>
<PickerButtons
confirmLabel={props.confirmLabel}
cancelLabel={props.cancelLabel}
onCancel={() => {
resetInnerValue()
timeSelectScrollToValue('start', props.value ? props.value[0] : getZeroDate(), false)
timeSelectScrollToValue('end', props.value ? props.value[1] : getZeroDate(), false)
setTimeout(() => { closePopover() }, 10)
}}
onConfirm={() => {
setInnerValue((value) => value, true)
if (innerValue.startDate && innerValue.endDate) {
let data = [innerValue.startDate, innerValue.endDate]
if (isAfter(innerValue.startDate, innerValue.endDate)) {
data = data.reverse()
}
timeSelectScrollToValue('start', data[0], false)
timeSelectScrollToValue('end', data[1], false)
} else {
timeSelectScrollToValue('start', getZeroDate(), false)
timeSelectScrollToValue('end', getZeroDate(), false)
}
setTimeout(() => { closePopover() }, 10)
}}
/>
</Container>
</Popover>
</Root>
)
})
Example #20
Source File: DateSelect.tsx From UUI with MIT License | 4 votes |
DateSelect = UUIFunctionComponent({
name: 'DateSelect',
nodes: {
Root: 'div',
Calendar: 'div',
WeekGrid: 'div',
WeekItem: 'div',
DayGrid: 'div',
DayItem: 'div',
},
propTypes: DateSelectPropTypes,
}, (props: DateSelectFeatureProps, { nodes, NodeDataProps }) => {
const {
Root, Calendar,
WeekGrid, WeekItem,
DayGrid, DayItem,
} = nodes
const betweenIncludeDates = useCallback((date: Date, range: [Date, Date] | Date[]) => {
return !isBefore(date, range[0]) && !isAfter(date, range[1])
}, [])
const dateInfo = useMemo(() => {
const firstDayInMonth = startOfMonth(props.yearMonth)
const weekdayOfFirstDayInMonth = getDay(firstDayInMonth)
const weekdays = range(0, 7).map((i) => {
let date = new Date(props.yearMonth)
date = startOfWeek(date)
date = add(date, { days: i })
return {
key: format(date, 'yyyy-MM-dd'),
date: date,
label: format(date, 'EEEEEE', { locale: zhCN }),
};
});
const days = range(
1 - weekdayOfFirstDayInMonth,
1 - weekdayOfFirstDayInMonth + 6*7,
).map((i) => {
const date = add(firstDayInMonth, { days: i - 1 })
const selected = props.selectedDates.findIndex((i) => isSameDay(date, i)) !== -1
const inSelectedRange = (() => {
if (props.selectedDates.length >= 2) {
return betweenIncludeDates(date, props.selectedDates)
}
return false;
})()
return {
key: format(date, 'yyyy-MM-dd'),
date: date,
label: getDate(date),
active: isSameMonth(props.yearMonth, date),
selected: selected,
inSelectedRange: inSelectedRange,
}
})
return {
weekdays,
days
}
}, [props.yearMonth, props.selectedDates, betweenIncludeDates])
return (
<Root>
<Calendar>
<WeekGrid>
{dateInfo.weekdays.map((weekday) => {
return (
<WeekItem key={weekday.key}>
{weekday.label}
</WeekItem>
);
})}
</WeekGrid>
<DayGrid
onMouseLeave={() => {
props.onHoverDateChange && props.onHoverDateChange(undefined)
}}
>
{dateInfo.days.map((day) => {
const hovering = props.hoverDate ? isSameDay(day.date, props.hoverDate) : false
const inHoverRange = (() => {
if (props.selectedDates.length === 1 && props.hoverDate) {
return betweenIncludeDates(day.date, [props.selectedDates[0], props.hoverDate].sort((i, j) => Number(i) - Number(j)))
}
return false
})()
return (
<DayItem
{...NodeDataProps({
'active': day.active,
'selected': day.selected,
'in-selected-range': day.inSelectedRange,
'in-hover-range': inHoverRange,
'hovering': hovering,
})}
key={day.key}
onClick={() => {
props.onSelect(day.date)
}}
onMouseEnter={() => {
props.onHoverDateChange && props.onHoverDateChange(day.date)
}}
onMouseLeave={() => {
props.onHoverDateChange && props.onHoverDateChange(undefined)
}}
>
{day.label}
</DayItem>
)
})}
</DayGrid>
</Calendar>
</Root>
)
})
Example #21
Source File: DateRangePicker.tsx From UUI with MIT License | 4 votes |
DateRangePicker = UUIFunctionComponent({
name: 'DateRangePicker',
nodes: {
Root: 'div',
ConnectIcon: Icons.ArrowRight,
CalendarIcon: Icons.Calendar,
Popover: UUIPopover,
TextField: UUITextField,
Activator: 'div',
Container: 'div',
Toolbar: 'div',
Main: 'div',
StartSection: 'div',
EndSection: 'div',
YearMonthSelect: UUIYearMonthSelect,
DateSelect: UUIDateSelect,
DateTimeShortcut: UUIDateTimeShortcut,
},
propTypes: DateRangePickerPropTypes,
}, (props: DateRangePickerFeatureProps, { nodes }) => {
const {
Root, ConnectIcon, CalendarIcon, Popover, TextField,
Activator, Container, Toolbar, Main, StartSection, EndSection,
YearMonthSelect, DateSelect, DateTimeShortcut,
} = nodes
const startInputRef = useRef<HTMLInputElement | null>(null)
const endInputRef = useRef<HTMLInputElement | null>(null)
const [whichFocusing, setWhichFocusing] = useState<'start' | 'end'>()
const [active, setActive] = useState(false)
const [hoverDate, setHoverDate] = useState<Date>()
const initialInnerValue = useMemo<DateRangePickerInnerValue>(() => {
if (props.value === null) {
return {
startDate: null,
endDate: null,
startInput: '',
endInput: '',
startYearMonth: startOfMonth(new Date),
endYearMonth: add(startOfMonth(new Date), { months: 1 }),
}
}
return {
startDate: props.value[0],
endDate: props.value[1],
startInput: formatDate(props.value[0]),
endInput: formatDate(props.value[1]),
startYearMonth: startOfMonth(props.value[0]),
endYearMonth: isSameMonth(props.value[0], props.value[1]) ? add(startOfMonth(props.value[1]), { months: 1 }) : props.value[1],
}
}, [props.value])
const [innerValue, setInnerValue, resetInnerValue] = usePendingValue<DateRangePickerInnerValue>(initialInnerValue, (value) => {
if (value.startDate && value.endDate) {
handleValueOnChange([value.startDate, value.endDate])
setActive(false)
}
}, { resetWhenInitialValueChanged: true })
const selectedDates = useMemo(() => {
return compact([innerValue.startDate, innerValue.endDate])
}, [innerValue.endDate, innerValue.startDate])
const handleValueOnChange = useCallback((value: [Date, Date] | null) => {
const sortedValue = value?.sort((i, j) => Number(i) - Number(j)) || null
props.onChange(sortedValue)
}, [props])
/**
*
*/
const handleInputOnSubmit = useCallback((type: 'start' | 'end') => {
if (innerValue.startDate && innerValue.endDate) {
const originalInput = formatDate(props.value && (type === 'start' ? props.value[0] : props.value[1]))
const input = type === 'start' ? innerValue.startInput : innerValue.endInput
if (originalInput === input) return;
try {
if (input === '') {
handleValueOnChange(null)
} else {
const result = tryParseDateFromString(input)
handleValueOnChange(type === 'start' ? [result, innerValue.endDate] : [innerValue.startDate, result])
}
} catch {
resetInnerValue()
}
}
}, [handleValueOnChange, innerValue.endInput, innerValue.endDate, innerValue.startInput, innerValue.startDate, props.value, resetInnerValue])
/**
* handle user change year or month in YearMonthSelect.
*/
const handleStartYearMonthSelect = useCallback((value: Date) => {
setInnerValue((oldValue) => {
const startYearMonthDate = value
let endYearMonthDate = oldValue.endYearMonth
if (!isBefore(startYearMonthDate, endYearMonthDate)) {
endYearMonthDate = add(startYearMonthDate, { months: 1 })
}
return {
...oldValue,
startYearMonth: startYearMonthDate,
endYearMonth: endYearMonthDate,
}
})
}, [setInnerValue])
const handleEndYearMonthSelect = useCallback((value: Date) => {
setInnerValue((oldValue) => {
const endYearMonthDate = value
let startYearMonthDate = oldValue.startYearMonth
if (!isAfter(endYearMonthDate, startYearMonthDate)) {
startYearMonthDate = add(endYearMonthDate, { months: -1 })
}
return {
...oldValue,
startYearMonth: startYearMonthDate,
endYearMonth: endYearMonthDate,
}
})
}, [setInnerValue])
/**
* handle user select date in DateSelect.
*/
const handleDateSelect = useCallback((value: Date) => {
let shouldSubmit = false
let newStartValue = innerValue.startDate
let newEndValue = innerValue.endDate
if (
(newStartValue !== null && newEndValue !== null) ||
(newStartValue === null && newEndValue === null)
) {
if (whichFocusing === 'end') {
newStartValue = null
newEndValue = value
} else {
newStartValue = value
newEndValue = null
}
} else {
if (newStartValue === null) newStartValue = value
if (newEndValue === null) newEndValue = value
if (isAfter(newStartValue, newEndValue)) {
const tmp = new Date(newStartValue)
newStartValue = new Date(newEndValue)
newEndValue = tmp
}
shouldSubmit = true
}
setInnerValue((oldValue) => {
return {
...oldValue,
startDate: newStartValue,
startInput: formatDate(newStartValue),
endDate: newEndValue,
endInput: formatDate(newEndValue),
}
}, shouldSubmit)
}, [innerValue.endDate, innerValue.startDate, setInnerValue, whichFocusing])
return (
<Root>
<Popover
placement={'bottom-start'}
active={active}
onClickAway={() => { setActive(false); resetInnerValue(); }}
activator={
<Activator
onClick={() => {
setActive(true)
setTimeout(() => {
if (whichFocusing === undefined && startInputRef.current) {
startInputRef.current.focus()
}
}, 0)
}}
>
<TextField
placeholder={props.startPlaceholder}
value={innerValue.startInput}
onChange={(value) => { setInnerValue((oldValue) => ({ ...oldValue, startInput: value })) }}
customize={{
Input: {
ref: startInputRef,
onFocus: () => {
setWhichFocusing('start')
},
onBlur: () => {
setWhichFocusing(undefined)
handleInputOnSubmit('start')
},
onKeyDown: (event) => {
if (event.key === 'Enter') {
handleInputOnSubmit('start')
}
}
}
}}
/>
<ConnectIcon />
<TextField
placeholder={props.endPlaceholder}
value={innerValue.endInput}
onChange={(value) => { setInnerValue((oldValue) => ({ ...oldValue, endInput: value })) }}
customize={{
Input: {
ref: endInputRef,
onFocus: () => {
setWhichFocusing('end')
},
onBlur: () => {
setWhichFocusing(undefined)
handleInputOnSubmit('end')
},
onKeyDown: (event) => {
if (event.key === 'Enter') {
handleInputOnSubmit('end')
}
}
}
}}
/>
<CalendarIcon />
</Activator>
}
>
<Container>
<Toolbar>
{props.shortcuts && (
<DateTimeShortcut
options={props.shortcuts}
onSelect={(value) => {
handleValueOnChange(value)
setActive(false)
}}
/>
)}
</Toolbar>
<Main tabIndex={-1}>
<StartSection>
<YearMonthSelect
value={innerValue.startYearMonth}
onChange={handleStartYearMonthSelect}
/>
<DateSelect
yearMonth={innerValue.startYearMonth}
selectedDates={selectedDates}
onSelect={handleDateSelect}
hoverDate={hoverDate}
onHoverDateChange={(date) => { setHoverDate(date) }}
/>
</StartSection>
<EndSection>
<YearMonthSelect
value={innerValue.endYearMonth}
onChange={handleEndYearMonthSelect}
/>
<DateSelect
yearMonth={innerValue.endYearMonth}
selectedDates={selectedDates}
onSelect={handleDateSelect}
hoverDate={hoverDate}
onHoverDateChange={(date) => { setHoverDate(date) }}
/>
</EndSection>
</Main>
</Container>
</Popover>
</Root>
)
})
Example #22
Source File: DonationTable.tsx From frontend with MIT License | 4 votes |
function DonationTable({ donations }: DonationTableProps) {
const { t, i18n } = useTranslation()
const [fromDate, setFromDate] = React.useState<Date | null>(null)
const [toDate, setToDate] = React.useState<Date | null>(null)
const [monthly, setMonthly] = React.useState(true)
const [oneTime, setOneTime] = React.useState(true)
const filteredByTypeDonations = useMemo(() => {
if (monthly && oneTime) {
return donations
}
if (!monthly && !oneTime) {
return []
}
if (monthly) {
return donations?.filter((d) => d.type !== 'donation')
}
if (oneTime) {
return donations?.filter((d) => d.type === 'donation')
}
return donations
}, [donations, monthly, oneTime])
const filteredDonations = useMemo(() => {
if (!fromDate && !toDate) {
return filteredByTypeDonations
}
if (fromDate && toDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isAfter(createdAtDate, fromDate) && isBefore(createdAtDate, toDate)
})
}
if (fromDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isAfter(createdAtDate, fromDate)
})
}
if (toDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isBefore(createdAtDate, toDate)
})
}
}, [filteredByTypeDonations, fromDate, toDate])
return (
<Card sx={{ padding: theme.spacing(2) }}>
<Grid container alignItems={'flex-start'} spacing={theme.spacing(2)}>
<Grid item xs={6} sm={3}>
<CheckboxLabel>{t('profile:donations.oneTime')}</CheckboxLabel>
<Checkbox
onChange={(e, checked) => setOneTime(checked)}
checked={oneTime}
name="oneTime"
/>
</Grid>
<Grid item xs={6} sm={3}>
<CheckboxLabel>{t('profile:donations.monthly')}</CheckboxLabel>
<Checkbox
onChange={(e, checked) => setMonthly(checked)}
checked={monthly}
name="monthly"
/>
</Grid>
<LocalizationProvider
locale={i18n.language === 'bg' ? bg : enUS}
dateAdapter={AdapterDateFns}>
<Grid item xs={12} sm={3}>
<DatePicker
label={t('profile:donations.fromDate')}
value={fromDate}
onChange={setFromDate}
renderInput={(params) => <TextField size="small" {...params} />}
/>
</Grid>
<Grid item xs={12} sm={3}>
<DatePicker
label={t('profile:donations.toDate')}
value={toDate}
onChange={setToDate}
renderInput={(params) => <TextField size="small" {...params} />}
/>
</Grid>
</LocalizationProvider>
</Grid>
{filteredDonations?.length ? (
<TableContainer>
<Table sx={{ minWidth: 650, backgroundColor: 'white' }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>№</TableCell>
<TableCell>{t('profile:donations.date')}</TableCell>
<TableCell>{t('profile:donations.type')}</TableCell>
<TableCell>{t('profile:donations.cause')}</TableCell>
<TableCell>{t('profile:donations.amount')}</TableCell>
<TableCell>{t('profile:donations.certificate')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredDonations.map((donation, index) => (
<TableRow key={index} sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
<TableCell component="th" scope="row">
{index + 1}
</TableCell>
<TableCell>
{format(parseISO(donation.createdAt), 'd.LL.yyyy', {
locale: i18n.language === 'bg' ? bg : enUS,
})}
</TableCell>
<TableCell>
<Avatar sx={{ background: darken(theme.palette.secondary.main, 0.175) }}>
<StarIcon />
</Avatar>
</TableCell>
<TableCell>{donation.targetVault.campaign.title}</TableCell>
<TableCell>{money(donation.amount)}</TableCell>
<TableCell>
<Button variant="outlined" disabled={donation.status != 'succeeded'}>
<Link target="_blank" href={routes.donation.viewCertificate(donation.id)}>
{t('profile:donations.download')} <ArrowForwardIcon />
</Link>
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
) : (
<Box sx={{ fontSize: 20, mt: 4 }}>Към момента няма направени дарения</Box>
)}
</Card>
)
}