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 (