From 3aee307e0dae604196a164c8b55f362eae59d61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Gonz=C3=A1lez=20Mu=C3=B1oz?= Date: Thu, 14 Nov 2024 19:36:42 +0100 Subject: [PATCH] create project form - WIP --- client/package.json | 5 +- .../src/app/auth/api/[...nextauth]/config.ts | 1 + client/src/app/layout.tsx | 4 +- client/src/app/projects/new/page.tsx | 41 ++ client/src/app/providers.tsx | 2 +- client/src/components/ui/accordion.tsx | 58 +++ client/src/components/ui/form.tsx | 24 +- client/src/components/ui/input.tsx | 4 +- client/src/components/ui/radio-group.tsx | 100 +++++ client/src/containers/overview/index.tsx | 2 +- .../projects/form/assumptions/columns.tsx | 61 +++ .../projects/form/assumptions/index.tsx | 148 +++++++ .../containers/projects/form/cell-value.tsx | 45 ++ .../cost-inputs-overrides/capex/columns.tsx | 67 +++ .../cost-inputs-overrides/capex/index.tsx | 141 +++++++ .../form/cost-inputs-overrides/constants.ts | 59 +++ .../form/cost-inputs-overrides/index.tsx | 40 ++ .../cost-inputs-overrides/opex/columns.tsx | 67 +++ .../form/cost-inputs-overrides/opex/index.tsx | 138 ++++++ .../cost-inputs-overrides/other/columns.tsx | 67 +++ .../cost-inputs-overrides/other/index.tsx | 138 ++++++ client/src/containers/projects/form/index.tsx | 34 ++ .../conservation-project-details/index.tsx | 323 ++++++++++++++ .../loss-rate.tsx | 107 +++++ .../t1-global-emission-factor.tsx | 64 +++ .../t2-national-emission-factors.tsx | 77 ++++ .../projects/form/setup/constants.ts | 13 + .../containers/projects/form/setup/index.tsx | 396 ++++++++++++++++++ .../restoration-project-detail/index.tsx | 125 ++++++ client/src/containers/projects/new/header.tsx | 32 ++ client/src/containers/projects/new/index.tsx | 171 ++++++++ .../src/containers/projects/new/sidebar.tsx | 74 ++++ client/src/lib/format.tsx | 2 + client/src/lib/query-keys.ts | 35 ++ pnpm-lock.yaml | 362 +++++++--------- shared/contracts/custom-projects.contract.ts | 25 +- shared/contracts/index.ts | 2 + .../carbon-inputs/emission-factors.entity.ts | 3 +- .../sequestration-rate.entity.ts | 2 +- shared/entities/custom-project.entity.ts | 10 + .../schemas/assumptions/assumptions.enums.ts | 19 + .../create-custom-project.schema.ts | 124 ++++-- 42 files changed, 2955 insertions(+), 257 deletions(-) create mode 100644 client/src/app/projects/new/page.tsx create mode 100644 client/src/components/ui/accordion.tsx create mode 100644 client/src/components/ui/radio-group.tsx create mode 100644 client/src/containers/projects/form/assumptions/columns.tsx create mode 100644 client/src/containers/projects/form/assumptions/index.tsx create mode 100644 client/src/containers/projects/form/cell-value.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/capex/columns.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/capex/index.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/constants.ts create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/index.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/opex/columns.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/opex/index.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/other/columns.tsx create mode 100644 client/src/containers/projects/form/cost-inputs-overrides/other/index.tsx create mode 100644 client/src/containers/projects/form/index.tsx create mode 100644 client/src/containers/projects/form/setup/conservation-project-details/index.tsx create mode 100644 client/src/containers/projects/form/setup/conservation-project-details/loss-rate.tsx create mode 100644 client/src/containers/projects/form/setup/conservation-project-details/t1-global-emission-factor.tsx create mode 100644 client/src/containers/projects/form/setup/conservation-project-details/t2-national-emission-factors.tsx create mode 100644 client/src/containers/projects/form/setup/constants.ts create mode 100644 client/src/containers/projects/form/setup/index.tsx create mode 100644 client/src/containers/projects/form/setup/restoration-project-detail/index.tsx create mode 100644 client/src/containers/projects/new/header.tsx create mode 100644 client/src/containers/projects/new/index.tsx create mode 100644 client/src/containers/projects/new/sidebar.tsx diff --git a/client/package.json b/client/package.json index af4d39cf..b2e4fbdf 100644 --- a/client/package.json +++ b/client/package.json @@ -7,11 +7,13 @@ "build": "next build", "start": "next start", "lint": "next lint", - "lint:fix": "next lint --fix" + "lint:fix": "next lint --fix", + "check-types": "tsc" }, "dependencies": { "@hookform/resolvers": "3.9.0", "@lukemorales/query-key-factory": "1.3.4", + "@radix-ui/react-accordion": "1.2.1", "@radix-ui/react-alert-dialog": "1.1.2", "@radix-ui/react-avatar": "^1.1.1", "@radix-ui/react-checkbox": "1.1.2", @@ -20,6 +22,7 @@ "@radix-ui/react-icons": "1.3.0", "@radix-ui/react-label": "2.1.0", "@radix-ui/react-popover": "1.1.2", + "@radix-ui/react-radio-group": "1.2.1", "@radix-ui/react-scroll-area": "1.2.0", "@radix-ui/react-select": "2.1.2", "@radix-ui/react-separator": "1.1.0", diff --git a/client/src/app/auth/api/[...nextauth]/config.ts b/client/src/app/auth/api/[...nextauth]/config.ts index f68bbb0e..e28316ce 100644 --- a/client/src/app/auth/api/[...nextauth]/config.ts +++ b/client/src/app/auth/api/[...nextauth]/config.ts @@ -1,4 +1,5 @@ import { cookies } from "next/headers"; + import { UserWithAccessToken } from "@shared/dtos/users/user.dto"; import { LogInSchema } from "@shared/schemas/auth/login.schema"; import type { diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx index 737ab4fd..664f8596 100644 --- a/client/src/app/layout.tsx +++ b/client/src/app/layout.tsx @@ -39,9 +39,7 @@ export default async function RootLayout({ -
- {children} -
+
{children}
diff --git a/client/src/app/projects/new/page.tsx b/client/src/app/projects/new/page.tsx new file mode 100644 index 00000000..db5a03cf --- /dev/null +++ b/client/src/app/projects/new/page.tsx @@ -0,0 +1,41 @@ +import { ACTIVITY } from "@shared/entities/activity.enum"; +import { ECOSYSTEM } from "@shared/entities/ecosystem.enum"; +import { + dehydrate, + HydrationBoundary, + QueryClient, +} from "@tanstack/react-query"; + +import { client } from "@/lib/query-client"; +import { queryKeys } from "@/lib/query-keys"; + +import CreateCustomProject from "@/containers/projects/new"; + +export default async function CreateCustomProjectPage() { + const queryClient = new QueryClient(); + + await queryClient.prefetchQuery({ + queryKey: queryKeys.customProjects.countries.queryKey, + queryFn: () => client.customProjects.getAvailableCountries.query(), + }); + + const defaultActivity = ACTIVITY.CONSERVATION; + const defaultEcosystem = ECOSYSTEM.SEAGRASS; + + await queryClient.prefetchQuery({ + queryKey: queryKeys.customProjects.assumptions({ + ecosystem: defaultEcosystem, + activity: defaultActivity, + }).queryKey, + queryFn: () => + client.customProjects.getDefaultAssumptions.query({ + query: { ecosystem: defaultEcosystem, activity: defaultActivity }, + }), + }); + + return ( + + + + ); +} diff --git a/client/src/app/providers.tsx b/client/src/app/providers.tsx index 26b8b313..c7616ed2 100644 --- a/client/src/app/providers.tsx +++ b/client/src/app/providers.tsx @@ -17,7 +17,7 @@ import { TooltipProvider } from "@/components/ui/tooltip"; let browserQueryClient: QueryClient | undefined = undefined; -function getQueryClient() { +export function getQueryClient() { if (isServer) { // Server: always make a new query client return makeQueryClient(); diff --git a/client/src/components/ui/accordion.tsx b/client/src/components/ui/accordion.tsx new file mode 100644 index 00000000..6e61c328 --- /dev/null +++ b/client/src/components/ui/accordion.tsx @@ -0,0 +1,58 @@ +"use client"; + +import * as React from "react"; + +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronsDownIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className, + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/client/src/components/ui/form.tsx b/client/src/components/ui/form.tsx index d5fcbe2e..20125513 100644 --- a/client/src/components/ui/form.tsx +++ b/client/src/components/ui/form.tsx @@ -16,6 +16,7 @@ import { Slot } from "@radix-ui/react-slot"; import { cn } from "@/lib/utils"; +import InfoButton from "@/components/ui/info-button"; import { Label } from "@/components/ui/label"; const Form = FormProvider; @@ -91,10 +92,29 @@ FormItem.displayName = "FormItem"; const FormLabel = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { + React.ComponentPropsWithoutRef & { + tooltip?: { + title: string; + content: React.ReactNode; + }; + } +>(({ className, tooltip, ...props }, ref) => { const { error, formItemId } = useFormField(); + if (tooltip) { + return ( +
+
+ ); + } + return (