Added Date export based on user timezone

This commit is contained in:
Joao Ramos
2024-01-16 18:42:12 +00:00
parent d0b0dfb16f
commit 01a9da3a5b
7 changed files with 92 additions and 6 deletions

View File

@@ -42,6 +42,7 @@
"iron-session": "^6.3.1",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"moment-timezone": "^0.5.44",
"next": "13.1.6",
"nodemailer": "^6.9.5",
"nodemailer-express-handlebars": "^6.1.0",

View File

@@ -0,0 +1,64 @@
import { Fragment, useState } from "react";
import { Combobox, Transition } from "@headlessui/react";
import { BsChevronExpand } from "react-icons/bs";
import moment from "moment-timezone";
interface Props {
value?: string;
onChange?: (value: string) => void;
disabled?: boolean;
}
export default function TimezoneSelect({
value,
disabled = false,
onChange,
}: Props) {
const [query, setQuery] = useState("");
const timezones = moment.tz.names();
const filteredTimezones = query === "" ? timezones : timezones.filter((x) => x.toLowerCase().includes(query.toLowerCase()));
return (
<>
<Combobox value={value} onChange={onChange} disabled={disabled}>
<div className="relative mt-1">
<div className="relative w-full cursor-default overflow-hidden ">
<Combobox.Input
className="py-6 w-full px-8 text-sm font-normal placeholder:text-mti-gray-cool bg-white disabled:bg-mti-gray-platinum/40 rounded-full border border-mti-gray-platinum focus:outline-none"
onChange={(e) => setQuery(e.target.value)}
/>
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-8">
<BsChevronExpand />
</Combobox.Button>
</div>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
afterLeave={() => setQuery("")}
>
<Combobox.Options className="absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-xl bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{filteredTimezones.map((timezone: string) => (
<Combobox.Option
key={timezone}
value={timezone}
className={({ active }) =>
`relative cursor-default select-none py-2 pl-10 pr-4 ${
active
? "bg-mti-purple-light text-white"
: "text-gray-900"
}`
}
>
{timezone}
</Combobox.Option>
))}
</Combobox.Options>
</Transition>
</div>
</Combobox>
</>
);
}

View File

@@ -78,6 +78,7 @@ export interface DemographicInformation {
gender: Gender;
employment: EmploymentStatus;
passport_id?: string;
timezone?: string;
}
export interface DemographicCorporateInformation {
@@ -85,6 +86,7 @@ export interface DemographicCorporateInformation {
phone: string;
gender: Gender;
position: string;
timezone?: string;
}
export type Gender = "male" | "female" | "other";

View File

@@ -28,6 +28,7 @@ import {
getRadialProgressPNG,
streamToBuffer,
} from "@/utils/pdf";
import moment from "moment-timezone";
interface GroupScoreSummaryHelper {
score: [number, number];
@@ -350,7 +351,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const pdfStream = await ReactPDF.renderToStream(
<GroupTestReport
title={title}
date={new Date(data.startDate).toLocaleString()}
date={moment(data.startDate).tz(user.demographicInformation?.timezone || 'UTC').format('ll HH:mm:ss')}
name={user.name}
email={user.email}
id={user.id}

View File

@@ -28,6 +28,7 @@ import {
getRadialProgressPNG,
streamToBuffer,
} from "@/utils/pdf";
import moment from "moment-timezone";
const db = getFirestore(app);
@@ -307,7 +308,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const pdfStream = await ReactPDF.renderToStream(
<TestReport
title={title}
date={new Date(stat.date).toLocaleString()}
date={moment(stat.date).tz(user.demographicInformation?.timezone || 'UTC').format('ll HH:mm:ss')}
name={user.name}
email={user.email}
id={user.id}

View File

@@ -11,13 +11,12 @@ import Button from "@/components/Low/Button";
import Link from "next/link";
import axios from "axios";
import {ErrorMessage} from "@/constants/errors";
import {RadioGroup} from "@headlessui/react";
import clsx from "clsx";
import {CorporateUser, EmploymentStatus, EMPLOYMENT_STATUS, Gender, User} from "@/interfaces/user";
import CountrySelect from "@/components/Low/CountrySelect";
import {shouldRedirectHome} from "@/utils/navigation.disabled";
import moment from "moment";
import {BsCamera, BsCameraFill} from "react-icons/bs";
import {BsCamera} from "react-icons/bs";
import {USER_TYPE_LABELS} from "@/resources/user";
import useGroups from "@/hooks/useGroups";
import useUsers from "@/hooks/useUsers";
@@ -25,7 +24,7 @@ import {convertBase64} from "@/utils";
import {Divider} from "primereact/divider";
import GenderInput from "@/components/High/GenderInput";
import EmploymentStatusInput from "@/components/High/EmploymentStatusInput";
import TimezoneSelect from "@/components/Low/TImezoneSelect";
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user;
@@ -83,7 +82,7 @@ function UserProfile({user, mutateUser}: Props) {
const [commercialRegistration, setCommercialRegistration] = useState<string | undefined>(
user.type === "agent" ? user.agentInformation?.commercialRegistration : undefined,
);
const [timezone, setTimezone] = useState<string>(user.demographicInformation?.timezone || 'UTC');
const {groups} = useGroups();
const {users} = useUsers();
@@ -146,6 +145,7 @@ function UserProfile({user, mutateUser}: Props) {
position: user?.type === "corporate" ? position : undefined,
gender,
passport_id,
timezone,
},
...(user.type === "corporate" ? {corporateInformation} : {}),
});
@@ -247,6 +247,13 @@ function UserProfile({user, mutateUser}: Props) {
</div>
);
const TimezoneInput = () => (
<div className="flex flex-col gap-3 w-1/2">
<label className="font-normal text-base text-mti-gray-dim">Timezone</label>
<TimezoneSelect value={timezone} onChange={setTimezone} />
</div>
);
return (
<Layout user={user}>
<section className="w-full flex flex-col gap-4 md:gap-8 px-4 py-8">
@@ -304,6 +311,9 @@ function UserProfile({user, mutateUser}: Props) {
<CountryInput />
<PhoneInput />
</DoubleColumnRow>
<DoubleColumnRow>
<TimezoneInput />
</DoubleColumnRow>
<Divider />

View File

@@ -4360,6 +4360,13 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment-timezone@^0.5.44:
version "0.5.44"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.44.tgz#a64a4e47b68a43deeab5ae4eb4f82da77cdf595f"
integrity sha512-nv3YpzI/8lkQn0U6RkLd+f0W/zy/JnoR5/EyPz/dNkPTBjA2jNLCVxaiQ8QpeLymhSZvX0wCL5s27NQWdOPwAw==
dependencies:
moment "^2.29.4"
moment@^2.29.4:
version "2.29.4"
resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz"