From d3e18b3c15bac0aaad3128a086fb5dce545f303d Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Sat, 20 Jul 2024 21:10:40 -0700 Subject: [PATCH 1/8] [vesting schedule] separated vestingSchedule separated vestingSchedule into cliffYears and vestingYears updated prisma tables for Share and Options to separate vestingSchedule into cliffYears and vestingYears with respectable trpc types and updated Shares and Options modal to separate vestingSchedule into two columns cliffYears and vestingYears --- prisma/schema.prisma | 24 +--- .../options/steps/vesting-details.tsx | 118 +++++++++++++---- .../shares/steps/general-details.tsx | 124 ++++++++++++++---- .../procedures/add-option.ts | 3 +- .../securities-router/procedures/add-share.ts | 3 +- src/trpc/routers/securities-router/schema.ts | 6 +- 6 files changed, 207 insertions(+), 71 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index dfe7f487e..07cdc22d0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -669,16 +669,6 @@ enum SecuritiesStatusEnum { PENDING } -enum VestingScheduleEnum { - VESTING_0_0_0 // Immediate vesting - VESTING_0_0_1 // 1 year cliff with no vesting - VESTING_4_1_0 // 4 years vesting every month with no cliff - VESTING_4_1_1 // 4 years vesting every month with 1 year cliff - VESTING_4_3_1 // 4 years vesting every 3 months with 1 year cliff - VESTING_4_6_1 // 4 years vesting every 6 months with 1 year cliff - VESTING_4_12_1 // 4 years vesting every year with 1 year cliff -} - enum ShareLegendsEnum { US_SECURITIES_ACT // US Securities Act of 1933 SALE_AND_ROFR // Sale and Right of first refusal @@ -697,9 +687,8 @@ model Share { debtCancelled Float? // Amount of debt cancelled otherContributions Float? // Other contributions - cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year - vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year - vestingSchedule VestingScheduleEnum + cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year + vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year companyLegends ShareLegendsEnum[] @@ -748,11 +737,10 @@ model Option { quantity Int exercisePrice Float - type OptionTypeEnum - status OptionStatusEnum @default(DRAFT) - cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year - vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year - vestingSchedule VestingScheduleEnum + type OptionTypeEnum + status OptionStatusEnum @default(DRAFT) + cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year + vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year issueDate DateTime expirationDate DateTime diff --git a/src/components/securities/options/steps/vesting-details.tsx b/src/components/securities/options/steps/vesting-details.tsx index d2555b088..f1972cf17 100644 --- a/src/components/securities/options/steps/vesting-details.tsx +++ b/src/components/securities/options/steps/vesting-details.tsx @@ -10,14 +10,18 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" import { Input } from "@/components/ui/input"; import { StepperModalFooter, StepperPrev, useStepper, } from "@/components/ui/stepper"; -import { VestingSchedule } from "@/lib/vesting"; -import { VestingScheduleEnum } from "@/prisma/enums"; import { useStockOptionFormValues } from "@/providers/stock-option-form-provider"; import type { RouterOutputs } from "@/trpc/shared"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -28,7 +32,8 @@ import { EmptySelect } from "../../shared/EmptySelect"; const formSchema = z.object({ equityPlanId: z.string(), - vestingSchedule: z.nativeEnum(VestingScheduleEnum), + cliffYears: z.coerce.number().min(0), + vestingYears: z.coerce.number().min(0), exercisePrice: z.coerce.number(), stakeholderId: z.string(), }); @@ -54,10 +59,10 @@ export const VestingDetails = (props: VestingDetailsProps) => { const disabled = !stakeholders?.length && !equityPlans?.length; - const vestingSchedileOpts = Object.keys(VestingSchedule).map((vKey) => ({ - value: vKey, - label: VestingSchedule[vKey] || "", - })); + // const vestingSchedileOpts = Object.keys(VestingSchedule).map((vKey) => ({ + // value: vKey, + // label: VestingSchedule[vKey] || "", + // })); const equityPlansOpts = equityPlans?.map(({ id, name }) => ({ value: id, @@ -76,22 +81,89 @@ export const VestingDetails = (props: VestingDetailsProps) => { className="flex flex-col gap-y-4" >
- ( - - Vesting schedule -
- field.onChange(option.value)} - /> -
- -
- )} - /> +
+
+ { + const { onChange, ...rest } = field; + return ( + + + + + Cliff Years + + +

Vesting starts after

+
+
+
+
+ + { + const { floatValue } = values; + onChange(floatValue); + }} + /> + +
+ + +
+ ) + }} + /> +
+ +
+ { + const { onChange, ...rest } = field; + return ( + + + + + + Vesting Years + + +

Vesting starts after

+
+
+
+
+ + { + const { floatValue } = values; + onChange(floatValue); + }} + /> + +
+ +
+ ) + }} + /> +
+
{equityPlans?.length ? ( { - const form = useForm({ + const form: UseFormReturn = useForm({ resolver: zodResolver(formSchema), }); const { next } = useStepper(); const { setValue } = useAddShareFormValues(); const status = Object.values(SecuritiesStatusEnum); - const vestingSchedule = Object.values(VestingScheduleEnum); const companyLegends = Object.values(ShareLegendsEnum); const handleSubmit = (data: TFormSchema) => { @@ -92,10 +96,10 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { label: share.name, })); - const vestingScheduleOpts = vestingSchedule.map((vs) => ({ - value: vs, - label: VestingSchedule[vs] || "", - })); + // const vestingScheduleOpts = vestingSchedule.map((vs) => ({ + // value: vs, + // label: VestingSchedule[vs] || "", + // })); const statusOpts = status.map((s) => ({ value: s, @@ -252,23 +256,91 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { />
+ +
+
+ { + const { onChange, ...rest } = field; + return ( + + + + + Cliff Years + + +

Vesting starts after

+
+
+
+
+ + { + const { floatValue } = values; + onChange(floatValue); + }} + /> + +
- ( - - Vesting schedule -
- field.onChange(option.value)} - /> -
- -
- )} - /> + +
+ ) + }} + /> +
+ +
+ { + const { onChange, ...rest } = field; + return ( + + + + + Vesting Years + + +

Vesting starts after

+
+
+
+ +
+ + { + const { floatValue } = values; + onChange(floatValue); + }} + /> + +
+ + +
+ ) + }} + /> +
+
Date: Sun, 21 Jul 2024 08:56:45 -0700 Subject: [PATCH 2/8] [build] fixed build errors fixed build errors, had to remove vestingSchedule from GET request on getSharesProcedure and getOptionsProcedure and replace with cliffYears and vestingYears --- src/components/update/editor.tsx | 8 +++----- .../routers/securities-router/procedures/get-options.ts | 3 ++- .../routers/securities-router/procedures/get-shares.ts | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/update/editor.tsx b/src/components/update/editor.tsx index 05ff455a1..3717aea50 100644 --- a/src/components/update/editor.tsx +++ b/src/components/update/editor.tsx @@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { DropdownButton } from "@/components/ui/dropdown-button"; import { api } from "@/trpc/react"; -import type { Block } from "@blocknote/core"; +import type { Block, PartialBlock } from "@blocknote/core"; import type { Update } from "@prisma/client"; import { RiArrowDownSLine } from "@remixicon/react"; import Link from "next/link"; @@ -166,14 +166,12 @@ const UpdatesEditor = ({ ]; const [title, setTitle] = useState(update?.title ?? ""); - const [content, setContent] = useState( - (update?.content as Block[]) ?? defaultContent, - ); + const [content, setContent] = useState(update?.content as Block[]) ?? defaultContent; const [html, setHtml] = useState(update?.html ?? ""); const [loading, setLoading] = useState(false); const editor = useCreateBlockNote({ - initialContent: content, + initialContent: content }); const draftMutation = api.update.save.useMutation({ diff --git a/src/trpc/routers/securities-router/procedures/get-options.ts b/src/trpc/routers/securities-router/procedures/get-options.ts index 808f758a5..eb8ef9e2a 100644 --- a/src/trpc/routers/securities-router/procedures/get-options.ts +++ b/src/trpc/routers/securities-router/procedures/get-options.ts @@ -17,7 +17,8 @@ export const getOptionsProcedure = withAuth.query( exercisePrice: true, type: true, status: true, - vestingSchedule: true, + cliffYears: true, + vestingYears: true, issueDate: true, expirationDate: true, vestingStartDate: true, diff --git a/src/trpc/routers/securities-router/procedures/get-shares.ts b/src/trpc/routers/securities-router/procedures/get-shares.ts index ead84143e..678647051 100644 --- a/src/trpc/routers/securities-router/procedures/get-shares.ts +++ b/src/trpc/routers/securities-router/procedures/get-shares.ts @@ -19,7 +19,8 @@ export const getSharesProcedure = withAuth.query( ipContribution: true, debtCancelled: true, otherContributions: true, - vestingSchedule: true, + cliffYears: true, + vestingYears: true, companyLegends: true, status: true, From f5c006ab48c3961d6923197b04056da4df6dc4e9 Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Sun, 21 Jul 2024 09:14:18 -0700 Subject: [PATCH 3/8] [vestingSchedule] fixed errors on server removed vestingSchedule at server level and replaced with cliffYears and vestingYears as vestingSchedule was separted into two fields --- src/server/api/routes/company/share/create.ts | 3 ++- src/server/api/schema/shares.ts | 16 ++++++++-------- src/server/services/shares/add-share.ts | 3 ++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/server/api/routes/company/share/create.ts b/src/server/api/routes/company/share/create.ts index d11c8231c..b19736fa3 100644 --- a/src/server/api/routes/company/share/create.ts +++ b/src/server/api/routes/company/share/create.ts @@ -90,7 +90,8 @@ const create = (app: PublicAPI) => { ipContribution: data.ipContribution ?? 0, debtCancelled: data.debtCancelled ?? 0, otherContributions: data.otherContributions ?? 0, - vestingSchedule: data.vestingSchedule ?? "", + cliffYears: data.cliffYears ?? "", + vestingYears: data.vestingYears ?? "", companyLegends: data.companyLegends ?? "", // Add missing fields issueDate: data.issueDate ?? new Date().toISOString(), // Add missing fields rule144Date: data.rule144Date ?? new Date().toISOString(), // Add missing fields diff --git a/src/server/api/schema/shares.ts b/src/server/api/schema/shares.ts index f7984b18e..b4cd9665b 100644 --- a/src/server/api/schema/shares.ts +++ b/src/server/api/schema/shares.ts @@ -2,14 +2,9 @@ import { z } from "@hono/zod-openapi"; import { SecuritiesStatusEnum, ShareLegendsEnum, - VestingScheduleEnum, } from "@prisma/client"; import { Share } from "next/font/google"; -const VestingScheduleArr = Object.values(VestingScheduleEnum) as [ - string, - ...string[], -]; const ShareLegendsArr = Object.values(ShareLegendsEnum) as [ string, ...string[], @@ -66,9 +61,14 @@ export const ShareSchema = z example: 0, }), - vestingSchedule: z.enum(VestingScheduleArr).openapi({ - description: "Vesting Schedule", - example: "VESTING_0_0_0", + cliffYears: z.number().nullish().openapi({ + description: "Cliff Years", + example: 1, + }), + + vestingYears: z.number().nullish().openapi({ + description: "Vesting Years", + example: 4, }), companyLegends: z diff --git a/src/server/services/shares/add-share.ts b/src/server/services/shares/add-share.ts index be322ba9c..1a9f33a25 100644 --- a/src/server/services/shares/add-share.ts +++ b/src/server/services/shares/add-share.ts @@ -31,7 +31,8 @@ export const addShare = async (input: AddShareType) => { ipContribution: input.ipContribution, debtCancelled: input.debtCancelled, otherContributions: input.otherContributions, - vestingSchedule: input.vestingSchedule, + cliffYears: input.cliffYears, + vestingYears: input.vestingYears, companyLegends: input.companyLegends, issueDate: new Date(input.issueDate), rule144Date: new Date(input.rule144Date), From 25bf87de12281c32adafcd8ca95a13d68251fc01 Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Sun, 21 Jul 2024 09:19:54 -0700 Subject: [PATCH 4/8] [type] fixed default value on cliffYears and vestingYears updated default value from empty string to 0 as default types for fields are numbers --- src/server/api/routes/company/share/create.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/api/routes/company/share/create.ts b/src/server/api/routes/company/share/create.ts index b19736fa3..64cba92ea 100644 --- a/src/server/api/routes/company/share/create.ts +++ b/src/server/api/routes/company/share/create.ts @@ -90,8 +90,8 @@ const create = (app: PublicAPI) => { ipContribution: data.ipContribution ?? 0, debtCancelled: data.debtCancelled ?? 0, otherContributions: data.otherContributions ?? 0, - cliffYears: data.cliffYears ?? "", - vestingYears: data.vestingYears ?? "", + cliffYears: data.cliffYears ?? 0, + vestingYears: data.vestingYears ?? 0, companyLegends: data.companyLegends ?? "", // Add missing fields issueDate: data.issueDate ?? new Date().toISOString(), // Add missing fields rule144Date: data.rule144Date ?? new Date().toISOString(), // Add missing fields From 41e3560b9e619af1484880c05c78f8ff4ca0d3fb Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Mon, 22 Jul 2024 15:40:55 -0700 Subject: [PATCH 5/8] [vestingSchedule] removed vestingSchedule import and fixed type errors --- src/server/api/routes/company/share/create.ts | 20 +++++++++++-------- src/server/api/schema/shares.ts | 3 ++- src/trpc/routers/securities-router/schema.ts | 1 - 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/server/api/routes/company/share/create.ts b/src/server/api/routes/company/share/create.ts index 64cba92ea..76e6f87e6 100644 --- a/src/server/api/routes/company/share/create.ts +++ b/src/server/api/routes/company/share/create.ts @@ -1,7 +1,7 @@ import { withCompanyAuth } from "@/server/api/auth"; import { ApiError, ErrorResponses } from "@/server/api/error"; import type { PublicAPI } from "@/server/api/hono"; -import { CreateShareSchema } from "@/server/api/schema/shares"; +import { CreateShareSchema, ShareSchemaType } from "@/server/api/schema/shares"; import { getHonoUserAgent, getIp } from "@/server/api/utils"; import { addShare } from "@/server/services/shares/add-share"; import { createRoute, z } from "@hono/zod-openapi"; @@ -61,7 +61,7 @@ const create = (app: PublicAPI) => { const { company, member, user } = await withCompanyAuth(c); const body = await c.req.json(); - const { success, message, data } = await addShare({ + const response = await addShare({ ...body, companyId: company.id, memberId: member.id, @@ -73,6 +73,10 @@ const create = (app: PublicAPI) => { }, }); + const data = response?.data; + const success = response?.success; + const message: string = response?.message.toString(); + if (!success || !data) { throw new ApiError({ code: "INTERNAL_SERVER_ERROR", @@ -81,8 +85,8 @@ const create = (app: PublicAPI) => { } // Ensure data matches ResponseSchema - const responseData = { - status: data.status as string, // Cast to string if necessary + const responseData: ShareSchemaType = { + status: data.status, // Cast to string if necessary certificateId: data.certificateId, quantity: data.quantity, pricePerShare: data.pricePerShare ?? 0, @@ -93,10 +97,10 @@ const create = (app: PublicAPI) => { cliffYears: data.cliffYears ?? 0, vestingYears: data.vestingYears ?? 0, companyLegends: data.companyLegends ?? "", // Add missing fields - issueDate: data.issueDate ?? new Date().toISOString(), // Add missing fields - rule144Date: data.rule144Date ?? new Date().toISOString(), // Add missing fields - vestingStartDate: data.vestingStartDate ?? new Date().toISOString(), // Add missing fields - boardApprovalDate: data.boardApprovalDate ?? new Date().toISOString(), // Add boardApprovalDate + issueDate: data.issueDate ? data.issueDate.toISOString() : new Date().toISOString(), // Add missing fields + rule144Date: data.rule144Date ? data.rule144Date.toISOString() : new Date().toISOString(), // Convert rule144Date to string + vestingStartDate: data.vestingStartDate ? data.vestingStartDate.toISOString() : new Date().toISOString(), // Add missing fields + boardApprovalDate: data.boardApprovalDate ? data.boardApprovalDate.toISOString() : new Date().toISOString(), // Add boardApprovalDate stakeholderId: data.stakeholderId ?? "", // Add stakeholderId shareClassId: data.shareClassId, }; diff --git a/src/server/api/schema/shares.ts b/src/server/api/schema/shares.ts index b4cd9665b..59414ad55 100644 --- a/src/server/api/schema/shares.ts +++ b/src/server/api/schema/shares.ts @@ -106,7 +106,7 @@ export const ShareSchema = z example: "cly13ipa40000i7ng42mv4x7b", }), - companyId: z.string().cuid().openapi({ + companyId: z.string().cuid().optional().openapi({ description: "Company ID", example: "clyvb28ak0000f1ngcn2i0p2m", }), @@ -135,6 +135,7 @@ export const CreateShareSchema = ShareSchema.omit({ createdAt: true, updatedAt: true, companyId: true, + status: true, }).openapi({ description: "Issue shares to a stakeholder in a company.", }); diff --git a/src/trpc/routers/securities-router/schema.ts b/src/trpc/routers/securities-router/schema.ts index 14b24b71e..0bc188601 100644 --- a/src/trpc/routers/securities-router/schema.ts +++ b/src/trpc/routers/securities-router/schema.ts @@ -2,7 +2,6 @@ import { OptionStatusEnum, OptionTypeEnum, ShareLegendsEnum, - VestingScheduleEnum, } from "@/prisma/enums"; import { SecuritiesStatusEnum } from "@prisma/client"; import { z } from "zod"; From 3200754f220ee2b1c12cacef881a11d94370753e Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Mon, 22 Jul 2024 17:35:06 -0700 Subject: [PATCH 6/8] [revert] revert un-needed change --- src/server/api/schema/shares.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/api/schema/shares.ts b/src/server/api/schema/shares.ts index 59414ad55..12b1e2033 100644 --- a/src/server/api/schema/shares.ts +++ b/src/server/api/schema/shares.ts @@ -135,7 +135,6 @@ export const CreateShareSchema = ShareSchema.omit({ createdAt: true, updatedAt: true, companyId: true, - status: true, }).openapi({ description: "Issue shares to a stakeholder in a company.", }); From 73453a4ba70ef6063e18cbf142030c07cb238617 Mon Sep 17 00:00:00 2001 From: Alfredoeb9 Date: Mon, 22 Jul 2024 17:59:45 -0700 Subject: [PATCH 7/8] [prisma] created migration as vestingSchedule was separated --- .../migration.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 prisma/migrations/20240723005834_separate_vesting_schedule/migration.sql diff --git a/prisma/migrations/20240723005834_separate_vesting_schedule/migration.sql b/prisma/migrations/20240723005834_separate_vesting_schedule/migration.sql new file mode 100644 index 000000000..253bf94c1 --- /dev/null +++ b/prisma/migrations/20240723005834_separate_vesting_schedule/migration.sql @@ -0,0 +1,15 @@ +/* + Warnings: + + - You are about to drop the column `vestingSchedule` on the `Option` table. All the data in the column will be lost. + - You are about to drop the column `vestingSchedule` on the `Share` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Option" DROP COLUMN "vestingSchedule"; + +-- AlterTable +ALTER TABLE "Share" DROP COLUMN "vestingSchedule"; + +-- DropEnum +DROP TYPE "VestingScheduleEnum"; From 38fec652a2f9a92c613647f321320c1c73f901f1 Mon Sep 17 00:00:00 2001 From: Puru D Date: Wed, 24 Jul 2024 22:56:46 -0500 Subject: [PATCH 8/8] chore: some minor cleanups --- .../options/steps/vesting-details.tsx | 35 +++++----- .../shares/steps/general-details.tsx | 69 +++++++++---------- src/components/update/editor.tsx | 6 +- src/server/api/routes/company/share/create.ts | 21 ++++-- src/server/api/schema/shares.ts | 6 +- 5 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/components/securities/options/steps/vesting-details.tsx b/src/components/securities/options/steps/vesting-details.tsx index f1972cf17..969d826ee 100644 --- a/src/components/securities/options/steps/vesting-details.tsx +++ b/src/components/securities/options/steps/vesting-details.tsx @@ -10,18 +10,18 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip" import { Input } from "@/components/ui/input"; import { StepperModalFooter, StepperPrev, useStepper, } from "@/components/ui/stepper"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { useStockOptionFormValues } from "@/providers/stock-option-form-provider"; import type { RouterOutputs } from "@/trpc/shared"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -85,7 +85,7 @@ export const VestingDetails = (props: VestingDetailsProps) => {
{ const { onChange, ...rest } = field; return ( @@ -93,10 +93,10 @@ export const VestingDetails = (props: VestingDetailsProps) => { - Cliff Years - + Vesting + -

Vesting starts after

+

Vesting starts over

@@ -105,6 +105,7 @@ export const VestingDetails = (props: VestingDetailsProps) => { 1 ? " years" : " year"} decimalScale={0} {...rest} customInput={Input} @@ -115,10 +116,9 @@ export const VestingDetails = (props: VestingDetailsProps) => { />
- - ) + ); }} /> @@ -126,17 +126,16 @@ export const VestingDetails = (props: VestingDetailsProps) => {
{ const { onChange, ...rest } = field; return ( - - Vesting Years - + Cliff +

Vesting starts after

@@ -148,6 +147,7 @@ export const VestingDetails = (props: VestingDetailsProps) => { thousandSeparator allowedDecimalSeparators={["%"]} decimalScale={0} + suffix={field.value > 1 ? " years" : " year"} {...rest} customInput={Input} onValueChange={(values) => { @@ -157,9 +157,10 @@ export const VestingDetails = (props: VestingDetailsProps) => { />
+ - ) + ); }} /> diff --git a/src/components/securities/shares/steps/general-details.tsx b/src/components/securities/shares/steps/general-details.tsx index 22faf9693..b03be7edb 100644 --- a/src/components/securities/shares/steps/general-details.tsx +++ b/src/components/securities/shares/steps/general-details.tsx @@ -12,12 +12,6 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip" import { Input } from "@/components/ui/input"; import { MultiSelector, @@ -33,14 +27,17 @@ import { useStepper, } from "@/components/ui/stepper"; import { - SecuritiesStatusEnum, - ShareLegendsEnum, -} from "@/prisma/enums"; + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { SecuritiesStatusEnum, ShareLegendsEnum } from "@/prisma/enums"; import { useAddShareFormValues } from "@/providers/add-share-form-provider"; import type { RouterOutputs } from "@/trpc/shared"; import { zodResolver } from "@hookform/resolvers/zod"; import { RiAddFill } from "@remixicon/react"; -import { useForm, UseFormReturn } from "react-hook-form"; +import { type UseFormReturn, useForm } from "react-hook-form"; import { NumericFormat } from "react-number-format"; import { z } from "zod"; @@ -256,12 +253,12 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { /> - +
{ const { onChange, ...rest } = field; return ( @@ -269,19 +266,21 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { - Cliff Years - + Vesting + -

Vesting starts after

+

Vesting starts over

+
1 ? " years" : " year"} {...rest} customInput={Input} onValueChange={(values) => { @@ -294,7 +293,7 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { - ) + ); }} />
@@ -302,7 +301,7 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => {
{ const { onChange, ...rest } = field; return ( @@ -310,33 +309,33 @@ export const GeneralDetails = ({ shareClasses = [] }: GeneralDetailsProps) => { - Vesting Years + Cliff

Vesting starts after

- -
- - { - const { floatValue } = values; - onChange(floatValue); - }} - /> - -
+
+ + 1 ? " years" : " year"} + {...rest} + customInput={Input} + onValueChange={(values) => { + const { floatValue } = values; + onChange(floatValue); + }} + /> + +
- ) + ); }} />
diff --git a/src/components/update/editor.tsx b/src/components/update/editor.tsx index 3717aea50..64742a4c4 100644 --- a/src/components/update/editor.tsx +++ b/src/components/update/editor.tsx @@ -166,12 +166,14 @@ const UpdatesEditor = ({ ]; const [title, setTitle] = useState(update?.title ?? ""); - const [content, setContent] = useState(update?.content as Block[]) ?? defaultContent; + const [content, setContent] = useState( + (update?.content as Block[]) ?? defaultContent, + ); const [html, setHtml] = useState(update?.html ?? ""); const [loading, setLoading] = useState(false); const editor = useCreateBlockNote({ - initialContent: content + initialContent: content, }); const draftMutation = api.update.save.useMutation({ diff --git a/src/server/api/routes/company/share/create.ts b/src/server/api/routes/company/share/create.ts index 76e6f87e6..c65fa806f 100644 --- a/src/server/api/routes/company/share/create.ts +++ b/src/server/api/routes/company/share/create.ts @@ -1,7 +1,10 @@ import { withCompanyAuth } from "@/server/api/auth"; import { ApiError, ErrorResponses } from "@/server/api/error"; import type { PublicAPI } from "@/server/api/hono"; -import { CreateShareSchema, ShareSchemaType } from "@/server/api/schema/shares"; +import { + CreateShareSchema, + type ShareSchemaType, +} from "@/server/api/schema/shares"; import { getHonoUserAgent, getIp } from "@/server/api/utils"; import { addShare } from "@/server/services/shares/add-share"; import { createRoute, z } from "@hono/zod-openapi"; @@ -97,10 +100,18 @@ const create = (app: PublicAPI) => { cliffYears: data.cliffYears ?? 0, vestingYears: data.vestingYears ?? 0, companyLegends: data.companyLegends ?? "", // Add missing fields - issueDate: data.issueDate ? data.issueDate.toISOString() : new Date().toISOString(), // Add missing fields - rule144Date: data.rule144Date ? data.rule144Date.toISOString() : new Date().toISOString(), // Convert rule144Date to string - vestingStartDate: data.vestingStartDate ? data.vestingStartDate.toISOString() : new Date().toISOString(), // Add missing fields - boardApprovalDate: data.boardApprovalDate ? data.boardApprovalDate.toISOString() : new Date().toISOString(), // Add boardApprovalDate + issueDate: data.issueDate + ? data.issueDate.toISOString() + : new Date().toISOString(), // Add missing fields + rule144Date: data.rule144Date + ? data.rule144Date.toISOString() + : new Date().toISOString(), // Convert rule144Date to string + vestingStartDate: data.vestingStartDate + ? data.vestingStartDate.toISOString() + : new Date().toISOString(), // Add missing fields + boardApprovalDate: data.boardApprovalDate + ? data.boardApprovalDate.toISOString() + : new Date().toISOString(), // Add boardApprovalDate stakeholderId: data.stakeholderId ?? "", // Add stakeholderId shareClassId: data.shareClassId, }; diff --git a/src/server/api/schema/shares.ts b/src/server/api/schema/shares.ts index 12b1e2033..3165b7c92 100644 --- a/src/server/api/schema/shares.ts +++ b/src/server/api/schema/shares.ts @@ -1,9 +1,5 @@ import { z } from "@hono/zod-openapi"; -import { - SecuritiesStatusEnum, - ShareLegendsEnum, -} from "@prisma/client"; -import { Share } from "next/font/google"; +import { SecuritiesStatusEnum, ShareLegendsEnum } from "@prisma/client"; const ShareLegendsArr = Object.values(ShareLegendsEnum) as [ string,