* refactor(profile): comment out change role feature * refactor(orders): update OrderServices and ServiceSelect components to utilize ServiceCard, and enhance service fields with duration in GraphQL types * refactor(schedule): implement forbidden order states to disable editing slots with active orders * fix(deploy): update SSH configuration to use dynamic port from secrets for improved flexibility * refactor(api/orders): simplify order creation logic by removing unnecessary validations and improving error handling * refactor(contact-row): replace role display logic with useIsMaster hook for improved clarity * refactor(profile/orders-list): update header text from "Общие записи" to "Недавние записи" for better clarity gql: GetOrders add sort slot.date:desc * refactor(profile/orders-list): enhance OrderCard component by adding avatarSource prop based on user role * feat(order-form): implement date selection with event highlighting and monthly view for available time slots * refactor(i18n/config): update timeZone from 'Europe/Amsterdam' to 'Europe/Moscow' * refactor(order-form/datetime-select): enhance date selection logic to include slot availability check * refactor(datetime-format): integrate dayjs timezone support with default Moscow timezone for date and time formatting * fix(contact-row): replace useIsMaster hook with isCustomerMaster utility for role display logic * refactor(service-card): replace formatTime with getMinutes for duration display * refactor(order-datetime): update date and time handling to use datetime_start and datetime_end for improved consistency * refactor(profile): streamline profile and slot pages by integrating session user retrieval and updating booking logic with BookButton component * fix(navigation): append query parameter to bottom-nav links and enhance back navigation logic in success page
88 lines
2.4 KiB
TypeScript
88 lines
2.4 KiB
TypeScript
/* eslint-disable import/no-unassigned-import */
|
||
import dayjs, { type ConfigType } from 'dayjs';
|
||
import timezone from 'dayjs/plugin/timezone';
|
||
import utc from 'dayjs/plugin/utc';
|
||
import 'dayjs/locale/ru';
|
||
|
||
type DateTime = Exclude<ConfigType, null | undefined>;
|
||
|
||
if (!dayjs.prototype.tz) {
|
||
dayjs.extend(utc);
|
||
dayjs.extend(timezone);
|
||
}
|
||
|
||
dayjs.locale('ru');
|
||
|
||
const DEFAULT_TZ = 'Europe/Moscow';
|
||
|
||
/**
|
||
* Склеивает дату (Date/string) и время (string, HH:mm) в datetime в нужной таймзоне, возвращает ISO строку в UTC
|
||
*/
|
||
export function combineDateAndTimeToUTC(
|
||
date: DateTime,
|
||
time: string,
|
||
tz: string = DEFAULT_TZ,
|
||
): string {
|
||
if (!date || !time) return '';
|
||
const dateString = dayjs(date).format('YYYY-MM-DD');
|
||
|
||
return dayjs.tz(`${dateString}T${time}`, tz).utc().toISOString();
|
||
}
|
||
|
||
export function formatDate(datetime: DateTime) {
|
||
return {
|
||
db: () => dayjs(datetime).utc().toISOString(),
|
||
user: (template?: string, tz: string = DEFAULT_TZ) => {
|
||
return dayjs
|
||
.utc(datetime)
|
||
.tz(tz)
|
||
.format(template || 'D MMMM YYYY');
|
||
},
|
||
};
|
||
}
|
||
|
||
export function formatTime(datetime: ConfigType) {
|
||
return {
|
||
db: () => dayjs(datetime).utc().toISOString(),
|
||
user: (tz: string = DEFAULT_TZ) => {
|
||
return dayjs.utc(datetime).tz(tz).format('HH:mm');
|
||
},
|
||
};
|
||
}
|
||
|
||
export function getDateUTCRange(date?: DateTime, tz: string = DEFAULT_TZ) {
|
||
return {
|
||
day: () => {
|
||
const startOfDay = dayjs(date).tz(tz).startOf('day').utc().toISOString();
|
||
const endOfDay = dayjs(date).tz(tz).endOf('day').utc().toISOString();
|
||
|
||
return { endOfDay, startOfDay };
|
||
},
|
||
month: () => {
|
||
const startOfMonth = dayjs(date).tz(tz).startOf('month').utc().toISOString();
|
||
const endOfMonth = dayjs(date).tz(tz).endOf('month').utc().toISOString();
|
||
|
||
return { endOfMonth, startOfMonth };
|
||
},
|
||
};
|
||
}
|
||
|
||
export function getMinutes(time: string) {
|
||
const [hours = '00', minutes = '00'] = time.split(':');
|
||
|
||
return Number.parseInt(hours, 10) * 60 + Number.parseInt(minutes, 10);
|
||
}
|
||
|
||
export function getTimeZoneLabel(tz: string = DEFAULT_TZ): string {
|
||
if (tz === DEFAULT_TZ) return 'МСК';
|
||
const offset = dayjs().tz(tz).format('Z');
|
||
|
||
return `GMT${offset}`;
|
||
}
|
||
|
||
export function sumTime(datetime: DateTime, durationMinutes: number) {
|
||
if (!datetime) return '';
|
||
|
||
return dayjs(datetime).add(durationMinutes, 'minute').toISOString();
|
||
}
|