Added Date export based on user timezone
This commit is contained in:
@@ -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",
|
||||
|
||||
64
src/components/Low/TImezoneSelect.tsx
Normal file
64
src/components/Low/TImezoneSelect.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 />
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user