This commit is contained in:
@@ -79,6 +79,161 @@ const currencyItems: ILabelValue[] = [
|
|||||||
{ label: "BRL", value: "BRL" },
|
{ label: "BRL", value: "BRL" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const allTimezones: Record<string, string> = {
|
||||||
|
"Pacific/Midway": "Midway Island, Samoa",
|
||||||
|
"Pacific/Honolulu": "Hawaii",
|
||||||
|
"America/Juneau": "Alaska",
|
||||||
|
"America/Boise": "Mountain Time",
|
||||||
|
"America/Dawson": "Dawson, Yukon",
|
||||||
|
"America/Chihuahua": "Chihuahua, La Paz, Mazatlan",
|
||||||
|
"America/Phoenix": "Arizona",
|
||||||
|
"America/Los_Angeles": "Pacific Time",
|
||||||
|
"America/Chicago": "Central Time",
|
||||||
|
"America/Regina": "Saskatchewan",
|
||||||
|
"America/Mexico_City": "Guadalajara, Mexico City, Monterrey",
|
||||||
|
"America/Belize": "Central America",
|
||||||
|
"America/Detroit": "Eastern Time",
|
||||||
|
"America/Bogota": "Bogota, Lima, Quito",
|
||||||
|
"America/Caracas": "Caracas, La Paz",
|
||||||
|
"America/Santiago": "Santiago",
|
||||||
|
"America/St_Johns": "Newfoundland and Labrador",
|
||||||
|
"America/Sao_Paulo": "Brasilia",
|
||||||
|
"America/Tijuana": "Tijuana",
|
||||||
|
"America/Montevideo": "Montevideo",
|
||||||
|
"America/Argentina/Buenos_Aires": "Buenos Aires, Georgetown",
|
||||||
|
"America/Godthab": "Greenland",
|
||||||
|
"Atlantic/Azores": "Azores",
|
||||||
|
"Atlantic/Cape_Verde": "Cape Verde Islands",
|
||||||
|
GMT: "UTC",
|
||||||
|
"Europe/London": "Edinburgh, London",
|
||||||
|
"Europe/Dublin": "Dublin",
|
||||||
|
"Europe/Lisbon": "Lisbon",
|
||||||
|
"Africa/Casablanca": "Casablanca, Monrovia",
|
||||||
|
"Atlantic/Canary": "Canary Islands",
|
||||||
|
"Europe/Belgrade": "Belgrade, Bratislava, Budapest, Ljubljana, Prague",
|
||||||
|
"Europe/Sarajevo": "Sarajevo, Skopje, Warsaw, Zagreb",
|
||||||
|
"Europe/Brussels": "Brussels, Copenhagen, Madrid, Paris",
|
||||||
|
"Europe/Amsterdam": "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna",
|
||||||
|
"Africa/Algiers": "West Central Africa",
|
||||||
|
"Europe/Bucharest": "Bucharest",
|
||||||
|
"Africa/Cairo": "Cairo",
|
||||||
|
"Europe/Helsinki": "Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius",
|
||||||
|
"Europe/Athens": "Athens",
|
||||||
|
"Asia/Jerusalem": "Jerusalem",
|
||||||
|
"Africa/Harare": "Harare, Pretoria",
|
||||||
|
"Europe/Moscow": "Istanbul, Minsk, Moscow, St. Petersburg, Volgograd",
|
||||||
|
"Asia/Kuwait": "Kuwait, Riyadh",
|
||||||
|
"Africa/Nairobi": "Nairobi",
|
||||||
|
"Asia/Baghdad": "Baghdad",
|
||||||
|
"Asia/Tehran": "Tehran",
|
||||||
|
"Asia/Dubai": "Abu Dhabi, Muscat",
|
||||||
|
"Asia/Baku": "Baku, Tbilisi, Yerevan",
|
||||||
|
"Asia/Kabul": "Kabul",
|
||||||
|
"Asia/Yekaterinburg": "Ekaterinburg",
|
||||||
|
"Asia/Karachi": "Islamabad, Karachi, Tashkent",
|
||||||
|
"Asia/Kolkata": "Chennai, Kolkata, Mumbai, New Delhi",
|
||||||
|
"Asia/Kathmandu": "Kathmandu",
|
||||||
|
"Asia/Dhaka": "Astana, Dhaka",
|
||||||
|
"Asia/Colombo": "Sri Jayawardenepura",
|
||||||
|
"Asia/Almaty": "Almaty, Novosibirsk",
|
||||||
|
"Asia/Rangoon": "Yangon Rangoon",
|
||||||
|
"Asia/Bangkok": "Bangkok, Hanoi, Jakarta",
|
||||||
|
"Asia/Krasnoyarsk": "Krasnoyarsk",
|
||||||
|
"Asia/Shanghai": "Beijing, Chongqing, Hong Kong SAR, Urumqi",
|
||||||
|
"Asia/Kuala_Lumpur": "Kuala Lumpur, Singapore",
|
||||||
|
"Asia/Taipei": "Taipei",
|
||||||
|
"Australia/Perth": "Perth",
|
||||||
|
"Asia/Irkutsk": "Irkutsk, Ulaanbaatar",
|
||||||
|
"Asia/Seoul": "Seoul",
|
||||||
|
"Asia/Tokyo": "Osaka, Sapporo, Tokyo",
|
||||||
|
"Asia/Yakutsk": "Yakutsk",
|
||||||
|
"Australia/Darwin": "Darwin",
|
||||||
|
"Australia/Adelaide": "Adelaide",
|
||||||
|
"Australia/Sydney": "Canberra, Melbourne, Sydney",
|
||||||
|
"Australia/Brisbane": "Brisbane",
|
||||||
|
"Australia/Hobart": "Hobart",
|
||||||
|
"Asia/Vladivostok": "Vladivostok",
|
||||||
|
"Pacific/Guam": "Guam, Port Moresby",
|
||||||
|
"Asia/Magadan": "Magadan, Solomon Islands, New Caledonia",
|
||||||
|
"Asia/Kamchatka": "Kamchatka, Marshall Islands",
|
||||||
|
"Pacific/Fiji": "Fiji Islands",
|
||||||
|
"Pacific/Auckland": "Auckland, Wellington",
|
||||||
|
"Pacific/Tongatapu": "Nuku'alofa",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTimezoneOffsetMinutes = (timezone: string, date = new Date()) => {
|
||||||
|
try {
|
||||||
|
const formatter = new Intl.DateTimeFormat("en", {
|
||||||
|
timeZone: timezone,
|
||||||
|
timeZoneName: "shortOffset",
|
||||||
|
});
|
||||||
|
const offset =
|
||||||
|
formatter
|
||||||
|
.formatToParts(date)
|
||||||
|
.find((part) => part.type === "timeZoneName")?.value ?? "";
|
||||||
|
const label = offset.replace(/^GMT/, "") || "+0";
|
||||||
|
const match = label.match(/^([+-])(\d{1,2})(?::(\d{2}))?$/);
|
||||||
|
|
||||||
|
if (!match) return 0;
|
||||||
|
|
||||||
|
const sign = match[1] === "-" ? -1 : 1;
|
||||||
|
const hours = Number(match[2]);
|
||||||
|
const minutes = Number(match[3] ?? 0);
|
||||||
|
|
||||||
|
return sign * (hours * 60 + minutes);
|
||||||
|
} catch {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatTimezoneOffset = (offsetMinutes: number) => {
|
||||||
|
const sign = offsetMinutes < 0 ? "-" : "+";
|
||||||
|
const absoluteMinutes = Math.abs(offsetMinutes);
|
||||||
|
const hours = Math.trunc(absoluteMinutes / 60);
|
||||||
|
const minutes = absoluteMinutes % 60;
|
||||||
|
|
||||||
|
return `${sign}${hours}:${minutes.toString().padStart(2, "0")}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasTimezoneDst = (timezone: string) => {
|
||||||
|
const januaryOffset = getTimezoneOffsetMinutes(
|
||||||
|
timezone,
|
||||||
|
new Date(new Date().getFullYear(), 0, 1),
|
||||||
|
);
|
||||||
|
const julyOffset = getTimezoneOffsetMinutes(
|
||||||
|
timezone,
|
||||||
|
new Date(new Date().getFullYear(), 6, 1),
|
||||||
|
);
|
||||||
|
|
||||||
|
return januaryOffset !== julyOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
const timezoneItems: ILabelValue[] = Object.entries(allTimezones)
|
||||||
|
.map(([timezone, name]) => {
|
||||||
|
const offsetMinutes = getTimezoneOffsetMinutes(timezone);
|
||||||
|
|
||||||
|
return {
|
||||||
|
timezone,
|
||||||
|
name,
|
||||||
|
hasDst: hasTimezoneDst(timezone),
|
||||||
|
offsetMinutes,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a, b) => a.offsetMinutes - b.offsetMinutes)
|
||||||
|
.filter((item, index, items) => {
|
||||||
|
return (
|
||||||
|
items.findIndex(
|
||||||
|
(timezone) =>
|
||||||
|
timezone.offsetMinutes === item.offsetMinutes &&
|
||||||
|
timezone.hasDst === item.hasDst,
|
||||||
|
) === index
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map(({ timezone, name, offsetMinutes }) => ({
|
||||||
|
label: `(GMT${formatTimezoneOffset(offsetMinutes)}) ${name}`,
|
||||||
|
value: timezone,
|
||||||
|
}));
|
||||||
|
|
||||||
export const createCompanyFormSections = ({
|
export const createCompanyFormSections = ({
|
||||||
editMode,
|
editMode,
|
||||||
id,
|
id,
|
||||||
@@ -315,15 +470,24 @@ export const createCompanyFormSections = ({
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: "input",
|
kind: "custom",
|
||||||
name: "timezone",
|
name: "timezone",
|
||||||
label: "Timezone",
|
|
||||||
type: "text",
|
|
||||||
className: "sm:col-span-2",
|
className: "sm:col-span-2",
|
||||||
rules: {
|
render: ({ register, errors }) => (
|
||||||
minLength: { value: 3, message: FormErrorMessages.minLength(3) },
|
<Select<ICreateCompanyCredentials>
|
||||||
maxLength: { value: 50, message: FormErrorMessages.maxLength(50) },
|
{...register("timezone")}
|
||||||
},
|
errors={errors}
|
||||||
|
name="timezone"
|
||||||
|
label="Timezone"
|
||||||
|
items={timezoneItems}
|
||||||
|
value={watch("timezone") ?? ""}
|
||||||
|
placeholder="Select timezone"
|
||||||
|
searchable
|
||||||
|
searchPlaceholder="Search timezone..."
|
||||||
|
clearable
|
||||||
|
onClear={() => setValue("timezone", "")}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user