From 01a9da3a5be3cc5fde31b38354d43f12be93a3b2 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Tue, 16 Jan 2024 18:42:12 +0000 Subject: [PATCH 1/3] Added Date export based on user timezone --- package.json | 1 + src/components/Low/TImezoneSelect.tsx | 64 +++++++++++++++++++++++ src/interfaces/user.ts | 2 + src/pages/api/assignments/[id]/export.tsx | 3 +- src/pages/api/stats/[id]/export.tsx | 3 +- src/pages/profile.tsx | 18 +++++-- yarn.lock | 7 +++ 7 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/components/Low/TImezoneSelect.tsx diff --git a/package.json b/package.json index 28d3f1f6..c7cb23e0 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/Low/TImezoneSelect.tsx b/src/components/Low/TImezoneSelect.tsx new file mode 100644 index 00000000..237cf781 --- /dev/null +++ b/src/components/Low/TImezoneSelect.tsx @@ -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 ( + <> + +
+
+ setQuery(e.target.value)} + /> + + + +
+ setQuery("")} + > + + {filteredTimezones.map((timezone: string) => ( + + `relative cursor-default select-none py-2 pl-10 pr-4 ${ + active + ? "bg-mti-purple-light text-white" + : "text-gray-900" + }` + } + > + {timezone} + + ))} + + +
+
+ + ); +} diff --git a/src/interfaces/user.ts b/src/interfaces/user.ts index 4a390a3f..dec052ef 100644 --- a/src/interfaces/user.ts +++ b/src/interfaces/user.ts @@ -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"; diff --git a/src/pages/api/assignments/[id]/export.tsx b/src/pages/api/assignments/[id]/export.tsx index b0a7755e..8bc10d4b 100644 --- a/src/pages/api/assignments/[id]/export.tsx +++ b/src/pages/api/assignments/[id]/export.tsx @@ -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( { const user = req.session.user; @@ -83,7 +82,7 @@ function UserProfile({user, mutateUser}: Props) { const [commercialRegistration, setCommercialRegistration] = useState( user.type === "agent" ? user.agentInformation?.commercialRegistration : undefined, ); - + const [timezone, setTimezone] = useState(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) { ); + const TimezoneInput = () => ( +
+ + +
+ ); + return (
@@ -304,6 +311,9 @@ function UserProfile({user, mutateUser}: Props) { + + + diff --git a/yarn.lock b/yarn.lock index 8646fe4a..29859e31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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" From f85a1f5601798ab3ec8a76a50a9ea1aa60445308 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Tue, 16 Jan 2024 23:00:58 +0000 Subject: [PATCH 2/3] Updated part of the correction display for Writing --- src/components/Solutions/Writing.tsx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/components/Solutions/Writing.tsx b/src/components/Solutions/Writing.tsx index fad9ff5a..9c5f39f9 100644 --- a/src/components/Solutions/Writing.tsx +++ b/src/components/Solutions/Writing.tsx @@ -12,19 +12,26 @@ export default function Writing({id, type, prompt, attachment, userSolutions, on const [isModalOpen, setIsModalOpen] = useState(false); const formatSolution = (solution: string, errors: {correction: string | null; misspelled: string}[]) => { - const errorRegex = new RegExp(errors.map((x) => `(${x.misspelled})`).join("|")); + const misspelled = errors.map((x) => x.misspelled); + console.log({misspelled}); + const errorRegex = new RegExp(errors.map((x) => `(${x.misspelled})`).join("|"), "g"); + console.log(errorRegex.global); return ( <> - {reactStringReplace(solution, errorRegex, (match) => { - const correction = errors.find((x) => x.misspelled === match)?.correction; + {solution.split(" ").map((word) => { + if (!misspelled.includes(word)) return <>{word} ; + const correction = errors.find((x) => x.misspelled === word)?.correction; return ( - - {match} - + <> + + {word} + {" "} + ); })} From 5540e4a3e6b0a81d5dbd77f6f2fbc9be48407413 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Tue, 16 Jan 2024 23:11:16 +0000 Subject: [PATCH 3/3] Updated the profile page a bit to accommodate recent changes --- src/pages/profile.tsx | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index 52a20db3..12806fbb 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -82,7 +82,7 @@ function UserProfile({user, mutateUser}: Props) { const [commercialRegistration, setCommercialRegistration] = useState( user.type === "agent" ? user.agentInformation?.commercialRegistration : undefined, ); - const [timezone, setTimezone] = useState(user.demographicInformation?.timezone || 'UTC'); + const [timezone, setTimezone] = useState(user.demographicInformation?.timezone || "UTC"); const {groups} = useGroups(); const {users} = useUsers(); @@ -248,7 +248,7 @@ function UserProfile({user, mutateUser}: Props) { ); const TimezoneInput = () => ( -
+
@@ -293,27 +293,29 @@ function UserProfile({user, mutateUser}: Props) { /> - - {user.type === "student" && ( - setPassportID(e)} - placeholder="Enter National ID or Passport number" - value={passport_id} - required - /> - )} {user.type === "agent" && } - + + {user.type === "student" ? ( + + setPassportID(e)} + placeholder="Enter National ID or Passport number" + value={passport_id} + required + /> + + + ) : ( - + )}