-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
1,487 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<typeof AccordionPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> | ||
>(({ className, ...props }, ref) => ( | ||
<AccordionPrimitive.Item | ||
ref={ref} | ||
className={cn("border-b", className)} | ||
{...props} | ||
/> | ||
)); | ||
AccordionItem.displayName = "AccordionItem"; | ||
|
||
const AccordionTrigger = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Trigger>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Header className="flex"> | ||
<AccordionPrimitive.Trigger | ||
ref={ref} | ||
className={cn( | ||
"flex flex-1 items-start justify-between py-4 text-left text-sm font-medium transition-all [&[data-state=open]>svg]:rotate-180", | ||
className, | ||
)} | ||
{...props} | ||
> | ||
{children} | ||
<ChevronsDownIcon className="[&[data-state=open]:hidden h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" /> | ||
</AccordionPrimitive.Trigger> | ||
</AccordionPrimitive.Header> | ||
)); | ||
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; | ||
|
||
const AccordionContent = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Content | ||
ref={ref} | ||
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down" | ||
{...props} | ||
> | ||
<div className={cn("pb-4 pt-0", className)}>{children}</div> | ||
</AccordionPrimitive.Content> | ||
)); | ||
AccordionContent.displayName = AccordionPrimitive.Content.displayName; | ||
|
||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; |
92 changes: 92 additions & 0 deletions
92
client/src/containers/projects/form/assumptions/columns.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import React from "react"; | ||
|
||
import { useFormContext } from "react-hook-form"; | ||
|
||
import { createColumnHelper } from "@tanstack/react-table"; | ||
|
||
import { formatNumber } from "@/lib/format"; | ||
|
||
import { CreateCustomProjectForm } from "@/containers/projects/form/setup"; | ||
|
||
import { | ||
FormControl, | ||
FormField, | ||
FormItem, | ||
FormMessage, | ||
} from "@/components/ui/form"; | ||
import { Input } from "@/components/ui/input"; | ||
import { Label } from "@/components/ui/label"; | ||
|
||
const columnHelper = createColumnHelper<{ | ||
label: string; | ||
property: `assumption.${keyof NonNullable<CreateCustomProjectForm["assumptions"]>}`; | ||
defaultValue: string; | ||
unit: string; | ||
value: string; | ||
}>(); | ||
|
||
export const COLUMNS = () => { | ||
const form = useFormContext<CreateCustomProjectForm>(); | ||
|
||
return [ | ||
columnHelper.accessor("label", { | ||
header: () => <span>Cost</span>, | ||
cell: (props) => { | ||
return ( | ||
<Label | ||
tooltip={{ | ||
title: props.getValue(), | ||
// todo: update with descriptions | ||
content: props.getValue(), | ||
}} | ||
> | ||
{props.getValue()} | ||
</Label> | ||
); | ||
}, | ||
}), | ||
columnHelper.accessor("defaultValue", { | ||
header: () => <span>Base value</span>, | ||
cell: (props) => { | ||
const value = props.getValue(); | ||
if (value === null || value === undefined) { | ||
return "-"; | ||
} | ||
|
||
if (!Number(value)) return value; | ||
|
||
return formatNumber(Number(value)); | ||
}, | ||
}), | ||
columnHelper.accessor("unit", { | ||
header: () => <span>Unit</span>, | ||
}), | ||
columnHelper.accessor("value", { | ||
header: () => <span>Override value</span>, | ||
cell: (props) => { | ||
return ( | ||
<FormField | ||
control={form.control} | ||
/* | ||
// @ts-expect-error fix later */ | ||
name={props.row.original.property} | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormControl> | ||
<Input | ||
type="number" | ||
placeholder="Insert value" | ||
min={0} | ||
{...field} | ||
value={field.value as number} | ||
/> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
); | ||
}, | ||
}), | ||
]; | ||
}; |
152 changes: 151 additions & 1 deletion
152
client/src/containers/projects/form/assumptions/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,153 @@ | ||
import { ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons"; | ||
import { | ||
flexRender, | ||
getCoreRowModel, | ||
useReactTable, | ||
} from "@tanstack/react-table"; | ||
|
||
// import { client } from "@/lib/query-client"; | ||
// import { queryKeys } from "@/lib/query-keys"; | ||
// import { cn } from "@/lib/utils"; | ||
|
||
import { COLUMNS } from "@/containers/projects/form/assumptions/columns"; | ||
import { CreateCustomProjectForm } from "@/containers/projects/form/setup"; | ||
|
||
import { | ||
Accordion, | ||
AccordionContent, | ||
AccordionItem, | ||
AccordionTrigger, | ||
} from "@/components/ui/accordion"; | ||
import { | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableHead, | ||
TableHeader, | ||
TableRow, | ||
} from "@/components/ui/table"; | ||
|
||
export const NO_DATA = []; | ||
|
||
const data: { | ||
label: string; | ||
// todo: this will be parsed in the client. We will only receive the key | ||
property: `assumption.${keyof NonNullable<CreateCustomProjectForm["assumptions"]>}`; | ||
defaultValue: string; | ||
unit: string; | ||
value: string; | ||
}[] = [ | ||
{ | ||
label: "Verification frequency", | ||
property: "assumption.verificationFrequency", | ||
defaultValue: "5", | ||
unit: "Years", | ||
value: "", | ||
}, | ||
{ | ||
label: "Discount rate", | ||
property: "assumption.discountRate", | ||
defaultValue: "0.05", | ||
unit: "%", | ||
value: "", | ||
}, | ||
]; | ||
|
||
export default function AssumptionsProjectForm() { | ||
return <div>AssumptionsProjectForm</div>; | ||
// const { queryKey } = queryKeys.customProjects.assumptions; | ||
// const { data, isSuccess } = | ||
// client.customProjects.getDefaultAssumptions.useQuery( | ||
// queryKey, | ||
// {}, | ||
// { | ||
// queryKey, | ||
// select: (data) => | ||
// Object.keys(data.body.data).map((key) => ({ | ||
// label: key, | ||
// unit: "N/A", | ||
// defaultValue: data.body.data[key], | ||
// value: "", | ||
// })), | ||
// }, | ||
// ); | ||
|
||
const table = useReactTable({ | ||
data, | ||
columns: COLUMNS(), | ||
getCoreRowModel: getCoreRowModel(), | ||
}); | ||
|
||
return ( | ||
<Accordion type="single" collapsible defaultValue="assumptions"> | ||
<AccordionItem value="assumptions" className="border-b-0"> | ||
<AccordionTrigger> | ||
<div className="flex flex-col gap-3"> | ||
<div className="flex items-baseline gap-2"> | ||
<h2 className="text-2xl font-medium">Assumptions</h2> | ||
<span className="font-normal text-muted-foreground"> | ||
optional | ||
</span> | ||
</div> | ||
<p className="font-normal text-muted-foreground"> | ||
Assumptions are applied across all projects, these can be left at | ||
default settings or can be specified to particular values. | ||
</p> | ||
</div> | ||
</AccordionTrigger> | ||
<AccordionContent className="pb-0"> | ||
<Table> | ||
<TableHeader> | ||
{table.getHeaderGroups().map((headerGroup) => ( | ||
<TableRow key={headerGroup.id} className="divide-x-0"> | ||
{headerGroup.headers.map((header) => { | ||
return ( | ||
<TableHead | ||
key={header.id} | ||
className="bg-transparent font-normal" | ||
> | ||
{header.isPlaceholder | ||
? null | ||
: flexRender( | ||
header.column.columnDef.header, | ||
header.getContext(), | ||
)} | ||
</TableHead> | ||
); | ||
})} | ||
</TableRow> | ||
))} | ||
</TableHeader> | ||
<TableBody> | ||
{table.getRowModel().rows?.length ? ( | ||
table.getRowModel().rows.map((row) => ( | ||
<TableRow | ||
key={row.id} | ||
className="divide-x-0 divide-y-0 border-b-0" | ||
> | ||
{row.getVisibleCells().map((cell) => ( | ||
<TableCell key={cell.id} className="py-3"> | ||
{flexRender( | ||
cell.column.columnDef.cell, | ||
cell.getContext(), | ||
)} | ||
</TableCell> | ||
))} | ||
</TableRow> | ||
)) | ||
) : ( | ||
<TableRow> | ||
<TableCell | ||
colSpan={COLUMNS.length} | ||
className="h-24 text-center" | ||
> | ||
No results. | ||
</TableCell> | ||
</TableRow> | ||
)} | ||
</TableBody> | ||
</Table> | ||
</AccordionContent> | ||
</AccordionItem> | ||
</Accordion> | ||
); | ||
} |
Oops, something went wrong.