From 4c946b184bcbb95d88d41430b2a672b5e4269bf8 Mon Sep 17 00:00:00 2001 From: Sargam Date: Wed, 24 Jul 2024 16:24:09 +0545 Subject: [PATCH] chore: checkpoint 1 --- package.json | 2 + pnpm-lock.yaml | 44 +++++++----- src/components/common/date-picker.tsx | 66 ++++++++++++++++++ src/components/onboarding/company-form.tsx | 16 +++-- .../options/steps/relevant-dates.tsx | 21 ++++-- .../shares/steps/relevant-dates.tsx | 30 +++++--- src/components/ui/calendar.tsx | 69 +++++++++++++++++++ src/trpc/routers/onboarding-router/schema.ts | 4 +- src/trpc/routers/securities-router/schema.ts | 18 ++--- 9 files changed, 218 insertions(+), 52 deletions(-) create mode 100644 src/components/common/date-picker.tsx create mode 100644 src/components/ui/calendar.tsx diff --git a/package.json b/package.json index 88e5a8805..7da0bf134 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.0", "cookie": "^0.6.0", + "date-fns": "^3.6.0", "dayjs": "^1.11.11", "hono": "^4.4.8", "html-to-image": "^1.11.11", @@ -102,6 +103,7 @@ "prisma-json-types-generator": "^3.0.4", "pushmodal": "^1.0.4", "react": "18.3.1", + "react-day-picker": "^8.10.1", "react-dom": "18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.51.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0aea01b9..0dc911986 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -161,6 +161,9 @@ importers: cookie: specifier: ^0.6.0 version: 0.6.0 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 dayjs: specifier: ^1.11.11 version: 1.11.11 @@ -224,6 +227,9 @@ importers: react: specifier: 18.3.1 version: 18.3.1 + react-day-picker: + specifier: ^8.10.1 + version: 8.10.1(date-fns@3.6.0)(react@18.3.1) react-dom: specifier: 18.2.0 version: 18.2.0(react@18.3.1) @@ -8730,10 +8736,10 @@ snapshots: '@aws-crypto/sha1-browser': 3.0.0 '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/client-sts': 3.577.0 + '@aws-sdk/client-sso-oidc': 3.577.0 + '@aws-sdk/client-sts': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/middleware-bucket-endpoint': 3.577.0 '@aws-sdk/middleware-expect-continue': 3.577.0 '@aws-sdk/middleware-flexible-checksums': 3.577.0 @@ -8788,13 +8794,13 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)': + '@aws-sdk/client-sso-oidc@3.577.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.577.0 + '@aws-sdk/client-sts': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -8831,7 +8837,6 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: - - '@aws-sdk/client-sts' - aws-crt '@aws-sdk/client-sso@3.577.0': @@ -8877,13 +8882,13 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sts@3.577.0': + '@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/client-sso-oidc': 3.577.0 '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/middleware-host-header': 3.577.0 '@aws-sdk/middleware-logger': 3.577.0 '@aws-sdk/middleware-recursion-detection': 3.577.0 @@ -8920,6 +8925,7 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt '@aws-sdk/core@3.576.0': @@ -8951,13 +8957,13 @@ snapshots: '@smithy/util-stream': 3.0.1 tslib: 2.6.2 - '@aws-sdk/credential-provider-ini@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0)': + '@aws-sdk/credential-provider-ini@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0))': dependencies: - '@aws-sdk/client-sts': 3.577.0 + '@aws-sdk/client-sts': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) '@aws-sdk/credential-provider-env': 3.577.0 '@aws-sdk/credential-provider-process': 3.577.0 '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.0.0 '@smithy/property-provider': 3.0.0 @@ -8968,14 +8974,14 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-node@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0)': + '@aws-sdk/credential-provider-node@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0))': dependencies: '@aws-sdk/credential-provider-env': 3.577.0 '@aws-sdk/credential-provider-http': 3.577.0 - '@aws-sdk/credential-provider-ini': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-ini': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0)(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/credential-provider-process': 3.577.0 '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)) '@aws-sdk/types': 3.577.0 '@smithy/credential-provider-imds': 3.0.0 '@smithy/property-provider': 3.0.0 @@ -9008,9 +9014,9 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.577.0)': + '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.577.0(@aws-sdk/client-sso-oidc@3.577.0))': dependencies: - '@aws-sdk/client-sts': 3.577.0 + '@aws-sdk/client-sts': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0) '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.0.0 '@smithy/types': 3.0.0 @@ -9137,7 +9143,7 @@ snapshots: '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.577.0)': dependencies: - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) + '@aws-sdk/client-sso-oidc': 3.577.0 '@aws-sdk/types': 3.577.0 '@smithy/property-provider': 3.0.0 '@smithy/shared-ini-file-loader': 3.0.0 diff --git a/src/components/common/date-picker.tsx b/src/components/common/date-picker.tsx new file mode 100644 index 000000000..196f8cbbe --- /dev/null +++ b/src/components/common/date-picker.tsx @@ -0,0 +1,66 @@ +"use client"; + +import { RiCalendar2Line as CalendarIcon } from "@remixicon/react"; +import * as React from "react"; + +import { Button } from "@/components/ui/button"; +import { Calendar } from "@/components/ui/calendar"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { cn } from "@/lib/utils"; +import { format } from "date-fns"; +import type { SelectSingleEventHandler } from "react-day-picker"; + +export type DatePickerProps = { + className?: string; + dateFormat?: string; + disabled?: boolean; + locale?: string; + selected: Date; + onSelect: SelectSingleEventHandler; + placeholder?: string; +}; + +const DatePicker = ({ + className, + dateFormat, + disabled, + locale, + selected, + onSelect, + placeholder, +}: DatePickerProps) => { + return ( + + + + + + { + if (disabled) return true; + return date > new Date() || date < new Date("1900-01-01"); + }} + initialFocus + /> + + + ); +}; + +export default DatePicker; diff --git a/src/components/onboarding/company-form.tsx b/src/components/onboarding/company-form.tsx index aa4f14796..ceb7344fb 100644 --- a/src/components/onboarding/company-form.tsx +++ b/src/components/onboarding/company-form.tsx @@ -32,10 +32,12 @@ import countries from "@/lib/countries"; import { cn, isFileExists, validateFile } from "@/lib/utils"; import { api } from "@/trpc/react"; import type { RouterOutputs } from "@/trpc/shared"; +import { format, isValid, parse } from "date-fns"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; import { useRef, useState } from "react"; import { toast } from "sonner"; +import DatePicker from "../common/date-picker"; import Loading from "../common/loading"; import { LinearCombobox } from "../ui/combobox"; @@ -73,9 +75,7 @@ export const CompanyForm = ({ type, data }: CompanyFormProps) => { company: { city: data?.company.city ?? "", incorporationCountry: data?.company.incorporationCountry ?? "", - incorporationDate: data?.company.incorporationDate - ? dayjsExt(data.company.incorporationDate).format("YYYY-MM-DD") - : "", + incorporationDate: data?.company.incorporationDate, incorporationState: data?.company.incorporationState ?? "", incorporationType: data?.company.incorporationType ?? "", name: data?.company.name ?? "", @@ -443,9 +443,13 @@ export const CompanyForm = ({ type, data }: CompanyFormProps) => { render={({ field }) => ( Incorporation date - - - +
+ +
)} diff --git a/src/components/securities/options/steps/relevant-dates.tsx b/src/components/securities/options/steps/relevant-dates.tsx index 369e25959..7efec4178 100644 --- a/src/components/securities/options/steps/relevant-dates.tsx +++ b/src/components/securities/options/steps/relevant-dates.tsx @@ -1,5 +1,6 @@ "use client"; +import DatePicker from "@/components/common/date-picker"; import { Button } from "@/components/ui/button"; import { Form, @@ -21,11 +22,11 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; const formSchema = z.object({ - boardApprovalDate: z.string().date(), - rule144Date: z.string().date(), - issueDate: z.string().date(), - expirationDate: z.string().date(), - vestingStartDate: z.string().date(), + boardApprovalDate: z.date(), + rule144Date: z.date(), + issueDate: z.date(), + expirationDate: z.date(), + vestingStartDate: z.date(), }); type TFormSchema = z.infer; @@ -53,7 +54,10 @@ export const RelevantDates = () => { Issue date - + @@ -67,7 +71,10 @@ export const RelevantDates = () => { Expiry date - + diff --git a/src/components/securities/shares/steps/relevant-dates.tsx b/src/components/securities/shares/steps/relevant-dates.tsx index e1553f3d4..caa21820f 100644 --- a/src/components/securities/shares/steps/relevant-dates.tsx +++ b/src/components/securities/shares/steps/relevant-dates.tsx @@ -1,5 +1,6 @@ "use client"; +import DatePicker from "@/components/common/date-picker"; import { Button } from "@/components/ui/button"; import { Form, @@ -9,7 +10,6 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; import { StepperModalFooter, StepperPrev, @@ -21,10 +21,10 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; const formSchema = z.object({ - boardApprovalDate: z.string().date(), - rule144Date: z.string().date(), - issueDate: z.string().date(), - vestingStartDate: z.string().date(), + boardApprovalDate: z.date(), + rule144Date: z.date(), + issueDate: z.date(), + vestingStartDate: z.date(), }); type TFormSchema = z.infer; @@ -54,7 +54,10 @@ export const RelevantDates = () => { Issue date - + @@ -69,7 +72,10 @@ export const RelevantDates = () => { Vesting start date - + @@ -87,7 +93,10 @@ export const RelevantDates = () => { Board approval date - + @@ -102,7 +111,10 @@ export const RelevantDates = () => { Rule 144 date - + diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx new file mode 100644 index 000000000..2ea41aa91 --- /dev/null +++ b/src/components/ui/calendar.tsx @@ -0,0 +1,69 @@ +"use client"; + +import { + RiArrowLeftWideLine as ChevronLeft, + RiArrowRightWideLine as ChevronRight, +} from "@remixicon/react"; +import type * as React from "react"; +import { DayPicker } from "react-day-picker"; + +import { buttonVariants } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; + +export type CalendarProps = React.ComponentProps; + +function Calendar({ + className, + classNames, + showOutsideDays = true, + ...props +}: CalendarProps) { + return ( + , + IconRight: ({ ...props }) => , + }} + {...props} + /> + ); +} +Calendar.displayName = "Calendar"; + +export { Calendar }; diff --git a/src/trpc/routers/onboarding-router/schema.ts b/src/trpc/routers/onboarding-router/schema.ts index e2def1311..daefa5e99 100644 --- a/src/trpc/routers/onboarding-router/schema.ts +++ b/src/trpc/routers/onboarding-router/schema.ts @@ -26,8 +26,8 @@ export const ZodCompanyMutationSchema = z.object({ incorporationType: z.string().min(1, { message: "Incorporation type is required", }), - incorporationDate: z.string().min(1, { - message: "Incorporation date is required", + incorporationDate: z.date({ + required_error: "Incorporation date is required", }), incorporationCountry: z.string().min(1, { message: "Incorporation country is required", diff --git a/src/trpc/routers/securities-router/schema.ts b/src/trpc/routers/securities-router/schema.ts index 03a8554af..b56628d95 100644 --- a/src/trpc/routers/securities-router/schema.ts +++ b/src/trpc/routers/securities-router/schema.ts @@ -17,11 +17,11 @@ export const ZodAddOptionMutationSchema = z.object({ type: z.nativeEnum(OptionTypeEnum), status: z.nativeEnum(OptionStatusEnum), vestingSchedule: z.nativeEnum(VestingScheduleEnum), - issueDate: z.string().date(), - expirationDate: z.string().date(), - vestingStartDate: z.string().date(), - boardApprovalDate: z.string().date(), - rule144Date: z.string().date(), + issueDate: z.date(), + expirationDate: z.date(), + vestingStartDate: z.date(), + boardApprovalDate: z.date(), + rule144Date: z.date(), documents: z.array( z.object({ bucketId: z.string(), @@ -59,10 +59,10 @@ export const ZodAddShareMutationSchema = z.object({ status: z.nativeEnum(SecuritiesStatusEnum), vestingSchedule: z.nativeEnum(VestingScheduleEnum), companyLegends: z.nativeEnum(ShareLegendsEnum).array(), - issueDate: z.string().date(), - rule144Date: z.string().date(), - vestingStartDate: z.string().date(), - boardApprovalDate: z.string().date(), + issueDate: z.date(), + rule144Date: z.date(), + vestingStartDate: z.date(), + boardApprovalDate: z.date(), documents: z.array( z.object({ bucketId: z.string(),