Update NextJS to 16.1.6 (#547)
Some checks failed
build and push / build_n_push (push) Has been cancelled
Some checks failed
build and push / build_n_push (push) Has been cancelled
* Update NextJS to 16.1.6 * Update Node in workflow * Fix rabbit comments * Fix types * Add engines field
This commit is contained in:
2
.github/workflows/build_and_push.yml
vendored
2
.github/workflows/build_and_push.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- name: setup-node
|
- name: setup-node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '20'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
4401
package-lock.json
generated
4401
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
65
package.json
65
package.json
@@ -2,6 +2,9 @@
|
|||||||
"name": "netbird-dashboard",
|
"name": "netbird-dashboard",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.9.0"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"copy": "copyfiles -f ./node_modules/@axa-fr/react-oidc/dist/OidcServiceWorker.js ./public",
|
"copy": "copyfiles -f ./node_modules/@axa-fr/react-oidc/dist/OidcServiceWorker.js ./public",
|
||||||
"copytrusted": "copyfiles -f ./public/local/OidcTrustedDomains.js ./public",
|
"copytrusted": "copyfiles -f ./public/local/OidcTrustedDomains.js ./public",
|
||||||
@@ -13,34 +16,34 @@
|
|||||||
"cypress:open": "cypress open"
|
"cypress:open": "cypress open"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@axa-fr/react-oidc": "^7.22.18",
|
"@axa-fr/react-oidc": "^7.26.3",
|
||||||
"@dagrejs/dagre": "^1.1.5",
|
"@dagrejs/dagre": "^1.1.5",
|
||||||
"@radix-ui/react-accordion": "^1.1.2",
|
"@radix-ui/react-accordion": "^1.2.12",
|
||||||
"@radix-ui/react-checkbox": "^1.0.4",
|
"@radix-ui/react-checkbox": "^1.3.3",
|
||||||
"@radix-ui/react-collapsible": "^1.0.3",
|
"@radix-ui/react-collapsible": "^1.1.12",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-hover-card": "^1.1.4",
|
"@radix-ui/react-hover-card": "^1.1.15",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
"@radix-ui/react-popover": "^1.0.7",
|
"@radix-ui/react-popover": "^1.1.15",
|
||||||
"@radix-ui/react-radio-group": "^1.1.3",
|
"@radix-ui/react-radio-group": "^1.3.8",
|
||||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||||
"@radix-ui/react-select": "^2.0.0",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-slider": "^1.1.2",
|
"@radix-ui/react-slider": "^1.3.6",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@radix-ui/react-switch": "^1.0.3",
|
"@radix-ui/react-switch": "^1.2.6",
|
||||||
"@radix-ui/react-tabs": "^1.0.4",
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
"@radix-ui/react-toast": "^1.1.5",
|
"@radix-ui/react-toast": "^1.2.15",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@tabler/icons-react": "^2.39.0",
|
"@tabler/icons-react": "^3.36.1",
|
||||||
"@tanstack/match-sorter-utils": "^8.8.4",
|
"@tanstack/match-sorter-utils": "^8.8.4",
|
||||||
"@tanstack/react-table": "^8.10.7",
|
"@tanstack/react-table": "^8.10.7",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/d3": "^7.4.3",
|
"@types/d3": "^7.4.3",
|
||||||
"@types/lodash": "^4.14.200",
|
"@types/lodash": "^4.14.200",
|
||||||
"@types/node": "20.10.6",
|
"@types/node": "20.10.6",
|
||||||
"@types/react": "^18",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^19",
|
||||||
"@types/react-window": "^1.8.8",
|
"@types/react-window": "^1.8.8",
|
||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"@xterm/xterm": "^5.5.0",
|
"@xterm/xterm": "^5.5.0",
|
||||||
@@ -49,8 +52,9 @@
|
|||||||
"chart.js": "^4.4.8",
|
"chart.js": "^4.4.8",
|
||||||
"chroma-js": "^3.1.2",
|
"chroma-js": "^3.1.2",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
|
"classnames": "^2.5.1",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"cmdk": "^0.2.0",
|
"cmdk": "^1.1.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
@@ -58,24 +62,23 @@
|
|||||||
"elkjs": "^0.10.0",
|
"elkjs": "^0.10.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
"flowbite": "^1.8.1",
|
"framer-motion": "^12.29.2",
|
||||||
"flowbite-react": "^0.6.4",
|
|
||||||
"framer-motion": "^10.16.4",
|
|
||||||
"ip-address": "^10.1.0",
|
"ip-address": "^10.1.0",
|
||||||
"ip-cidr": "^3.1.0",
|
"ip-cidr": "^3.1.0",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"lodash": "^4.17.23",
|
"lodash": "^4.17.23",
|
||||||
"lucide-react": "^0.539.0",
|
"lucide-react": "^0.539.0",
|
||||||
"next": "^14.2.35",
|
"next": "^16.1.6",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
"punycode": "^2.3.1",
|
"punycode": "^2.3.1",
|
||||||
"react": "^18.3.1",
|
"react": "^19.2.4",
|
||||||
"react-day-picker": "^8.9.1",
|
"react-day-picker": "^9.13.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^19.2.4",
|
||||||
"react-ga4": "^2.1.0",
|
"react-ga4": "^2.1.0",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-hotjar": "^6.2.0",
|
"react-hotjar": "^6.3.1",
|
||||||
"react-hotkeys-hook": "^4.4.1",
|
"react-hotkeys-hook": "^4.4.1",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-jwt": "^1.2.0",
|
"react-jwt": "^1.2.0",
|
||||||
"react-loading-skeleton": "^3.3.1",
|
"react-loading-skeleton": "^3.3.1",
|
||||||
"react-responsive": "^9.0.2",
|
"react-responsive": "^9.0.2",
|
||||||
@@ -91,7 +94,7 @@
|
|||||||
"@types/chroma-js": "^3.1.1",
|
"@types/chroma-js": "^3.1.1",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-config-next": "^16.0.5",
|
"eslint-config-next": "^16.1.6",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prettier": "3.0.3",
|
"prettier": "3.0.3",
|
||||||
"tailwindcss": "^3.4.17"
|
"tailwindcss": "^3.4.17"
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
html{
|
||||||
|
@apply bg-nb-gray;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@apply text-2xl font-medium text-gray-700 dark:text-nb-gray-100 my-1;
|
@apply text-2xl font-medium text-gray-700 dark:text-nb-gray-100 my-1;
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
import { Checkbox } from "@components/Checkbox";
|
|
||||||
import { Input } from "@components/Input";
|
|
||||||
import { Popover, PopoverContent } from "@components/Popover";
|
|
||||||
import { useElementSize } from "@hooks/useElementSize";
|
|
||||||
import { Anchor } from "@radix-ui/react-popover";
|
|
||||||
import * as React from "react";
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
|
||||||
import { FaWindows } from "react-icons/fa6";
|
|
||||||
|
|
||||||
type Props = {};
|
|
||||||
export const AutoCompleteInput = ({}: Props) => {
|
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const [elementWidth, { width }] = useElementSize<HTMLDivElement>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const input = inputRef.current;
|
|
||||||
|
|
||||||
const onFocus = () => {
|
|
||||||
setOpen(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (input) {
|
|
||||||
inputRef.current.addEventListener("focus", onFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (input) {
|
|
||||||
inputRef.current.removeEventListener("focus", onFocus);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={"z-10 relative"}>
|
|
||||||
<Popover modal={false} open={open} onOpenChange={setOpen}>
|
|
||||||
<Anchor ref={elementWidth}>
|
|
||||||
<Input
|
|
||||||
placeholder={"11"}
|
|
||||||
ref={inputRef}
|
|
||||||
maxWidthClass={"max-w-[200px]"}
|
|
||||||
customPrefix={
|
|
||||||
<div className={"flex items-center gap-2"}>
|
|
||||||
<Checkbox></Checkbox>
|
|
||||||
<div
|
|
||||||
className={"flex gap-2 items-center text-sm text-nb-gray-200"}
|
|
||||||
>
|
|
||||||
<FaWindows className={"text-sky-600 text-lg"} />
|
|
||||||
Windows
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Anchor>
|
|
||||||
|
|
||||||
<PopoverContent
|
|
||||||
hideWhenDetached={false}
|
|
||||||
className="w-full p-0 shadow-sm shadow-nb-gray-950"
|
|
||||||
style={{
|
|
||||||
width: width,
|
|
||||||
}}
|
|
||||||
forceMount={true}
|
|
||||||
align="start"
|
|
||||||
side={"bottom"}
|
|
||||||
sideOffset={10}
|
|
||||||
onOpenAutoFocus={(event) => event.preventDefault()}
|
|
||||||
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
||||||
onInteractOutside={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (event.target !== inputRef.current) {
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerDownOutside={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (event.target !== inputRef.current) {
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onFocusOutside={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (event.target !== inputRef.current) {
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
></PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -53,13 +53,10 @@ const TooltipContent = React.forwardRef<
|
|||||||
<TooltipPrimitive.Portal>
|
<TooltipPrimitive.Portal>
|
||||||
<TooltipPrimitive.Content
|
<TooltipPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
asChild={true}
|
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(tooltipVariants({ variant }), className)}
|
className={cn(tooltipVariants({ variant }), className)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
/>
|
||||||
<div>{props.children}</div>
|
|
||||||
</TooltipPrimitive.Content>
|
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipPrimitive.Portal>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
import {
|
import {
|
||||||
MemoizedScrollArea,
|
MemoizedScrollArea,
|
||||||
MemoizedScrollAreaViewport,
|
ScrollAreaViewport,
|
||||||
} from "@components/ScrollArea";
|
} from "@components/ScrollArea";
|
||||||
import { cn } from "@utils/helpers";
|
import { cn } from "@utils/helpers";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import {
|
||||||
|
forwardRef,
|
||||||
|
memo,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
||||||
|
|
||||||
|
const VirtuosoScroller = forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>((props, ref) => <ScrollAreaViewport ref={ref} {...props} />);
|
||||||
|
|
||||||
type Props<T extends { id?: string }> = {
|
type Props<T extends { id?: string }> = {
|
||||||
items: T[];
|
items: T[];
|
||||||
onSelect: (item: T) => void;
|
onSelect: (item: T) => void;
|
||||||
@@ -183,7 +196,7 @@ export function VirtualScrollAreaList<T extends { id?: string }>({
|
|||||||
}}
|
}}
|
||||||
style={virtuosoHeight}
|
style={virtuosoHeight}
|
||||||
components={{
|
components={{
|
||||||
Scroller: MemoizedScrollAreaViewport,
|
Scroller: VirtuosoScroller,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</MemoizedScrollArea>
|
</MemoizedScrollArea>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||||
import { DialogTriggerProps } from "@radix-ui/react-dialog";
|
import { DialogTriggerProps } from "@radix-ui/react-dialog";
|
||||||
|
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
||||||
import { cn } from "@utils/helpers";
|
import { cn } from "@utils/helpers";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@@ -74,18 +75,19 @@ const ModalContent = React.forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<>
|
<VisuallyHidden asChild>
|
||||||
{children}
|
<DialogPrimitive.Title>Dialog</DialogPrimitive.Title>
|
||||||
{showClose && (
|
</VisuallyHidden>
|
||||||
<DialogPrimitive.Close
|
{children}
|
||||||
data-cy={"modal-close"}
|
{showClose && (
|
||||||
className="absolute right-4 z-10 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400"
|
<DialogPrimitive.Close
|
||||||
>
|
data-cy={"modal-close"}
|
||||||
<X className="h-4 w-4" />
|
className="absolute right-4 z-10 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400"
|
||||||
<span className="sr-only">Close</span>
|
>
|
||||||
</DialogPrimitive.Close>
|
<X className="h-4 w-4" />
|
||||||
)}
|
<span className="sr-only">Close</span>
|
||||||
</>
|
</DialogPrimitive.Close>
|
||||||
|
)}
|
||||||
</DialogPrimitive.Content>
|
</DialogPrimitive.Content>
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
@@ -129,18 +131,19 @@ const SidebarModalContent = React.forwardRef<
|
|||||||
}}
|
}}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<>
|
<VisuallyHidden asChild>
|
||||||
{children}
|
<DialogPrimitive.Title>Dialog</DialogPrimitive.Title>
|
||||||
{showClose && (
|
</VisuallyHidden>
|
||||||
<DialogPrimitive.Close
|
{children}
|
||||||
data-cy={"modal-close"}
|
{showClose && (
|
||||||
className="absolute right-4 z-10 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400"
|
<DialogPrimitive.Close
|
||||||
>
|
data-cy={"modal-close"}
|
||||||
<X className="h-4 w-4" />
|
className="absolute right-4 z-10 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400"
|
||||||
<span className="sr-only">Close</span>
|
>
|
||||||
</DialogPrimitive.Close>
|
<X className="h-4 w-4" />
|
||||||
)}
|
<span className="sr-only">Close</span>
|
||||||
</>
|
</DialogPrimitive.Close>
|
||||||
|
)}
|
||||||
</DialogPrimitive.Content>
|
</DialogPrimitive.Content>
|
||||||
</div>
|
</div>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
|
|||||||
@@ -14,11 +14,6 @@ import {
|
|||||||
TableWrapper,
|
TableWrapper,
|
||||||
} from "@components/table/Table";
|
} from "@components/table/Table";
|
||||||
import NoResults from "@components/ui/NoResults";
|
import NoResults from "@components/ui/NoResults";
|
||||||
import {
|
|
||||||
Accordion,
|
|
||||||
AccordionContent,
|
|
||||||
AccordionItem,
|
|
||||||
} from "@radix-ui/react-accordion";
|
|
||||||
import { RankingInfo } from "@tanstack/match-sorter-utils";
|
import { RankingInfo } from "@tanstack/match-sorter-utils";
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
@@ -493,117 +488,97 @@ export function DataTable<TData, TValue>({
|
|||||||
</TableHeaderComponent>
|
</TableHeaderComponent>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Accordion
|
<TableBodyComponent
|
||||||
asChild={true}
|
className={cn(
|
||||||
type={"multiple"}
|
"relative",
|
||||||
value={accordion}
|
data == undefined && "blur-sm",
|
||||||
onValueChange={setAccordion}
|
wrapperClassName,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<TableBodyComponent
|
{table.getRowModel().rows?.length ? (
|
||||||
className={cn(
|
table.getRowModel().rows.map((row) => {
|
||||||
"relative",
|
const expandedRow = renderExpandedRow?.(row.original);
|
||||||
data == undefined && "blur-sm",
|
const rowId = row.original.id ?? row.id;
|
||||||
wrapperClassName,
|
const isExpanded = accordion?.includes(rowId);
|
||||||
)}
|
const rowContent = (
|
||||||
>
|
<React.Fragment key={row.id}>
|
||||||
{table.getRowModel().rows?.length ? (
|
<TableRowComponent
|
||||||
table.getRowModel().rows.map((row) => {
|
minimal={minimal}
|
||||||
const expandedRow = renderExpandedRow?.(row.original);
|
data-row-id={rowId}
|
||||||
const rowContent = (
|
className={cn(
|
||||||
<AccordionItem
|
(onRowClick || renderExpandedRow) &&
|
||||||
value={row.original.id}
|
"relative group/accordion",
|
||||||
asChild={true}
|
(onRowClick || expandedRow) && "cursor-pointer",
|
||||||
key={row.id}
|
rowClassName,
|
||||||
>
|
)}
|
||||||
<>
|
data-state={row.getIsSelected() && "selected"}
|
||||||
<TableRowComponent
|
data-accordion={isExpanded ? "opened" : "closed"}
|
||||||
minimal={minimal}
|
onClick={(e) => {
|
||||||
data-row-id={row.original.id}
|
if (expandedRow) {
|
||||||
className={cn(
|
e.preventDefault();
|
||||||
(onRowClick || renderExpandedRow) &&
|
e.stopPropagation();
|
||||||
"relative group/accordion",
|
setAccordion((prev) => {
|
||||||
(onRowClick || expandedRow) && "cursor-pointer",
|
if (prev?.includes(rowId)) {
|
||||||
rowClassName,
|
return prev.filter(
|
||||||
)}
|
(item) => item !== rowId,
|
||||||
data-state={row.getIsSelected() && "selected"}
|
);
|
||||||
data-accordion={
|
} else {
|
||||||
accordion?.includes(row.original.id)
|
return [...(prev ?? []), rowId];
|
||||||
? "opened"
|
|
||||||
: "closed"
|
|
||||||
}
|
|
||||||
onClick={(e) => {
|
|
||||||
if (expandedRow) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
setAccordion((prev) => {
|
|
||||||
if (prev?.includes(row.original.id)) {
|
|
||||||
return prev.filter(
|
|
||||||
(item) => item !== row.original.id,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return [...(prev ?? []), row.original.id];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCellComponent
|
||||||
|
key={cell.id}
|
||||||
|
className={cn("relative", tableCellClassName)}
|
||||||
|
minimal={minimal}
|
||||||
|
inset={inset}
|
||||||
|
onClick={() => {
|
||||||
|
onRowClick && onRowClick(row, cell.column.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<>
|
<div
|
||||||
{row.getVisibleCells().map((cell) => (
|
className={
|
||||||
<TableCellComponent
|
"absolute left-0 top-0 w-full h-full z-0"
|
||||||
key={cell.id}
|
}
|
||||||
className={cn("relative", tableCellClassName)}
|
></div>
|
||||||
minimal={minimal}
|
<div className={"relative z-[1]"}>
|
||||||
inset={inset}
|
{flexRender(
|
||||||
onClick={() => {
|
cell.column.columnDef.cell,
|
||||||
onRowClick &&
|
cell.getContext(),
|
||||||
onRowClick(row, cell.column.id);
|
)}
|
||||||
}}
|
</div>
|
||||||
>
|
</TableCellComponent>
|
||||||
<div
|
))}
|
||||||
className={
|
</TableRowComponent>
|
||||||
"absolute left-0 top-0 w-full h-full z-0"
|
|
||||||
}
|
|
||||||
></div>
|
|
||||||
<div className={"relative z-[1]"}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext(),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</TableCellComponent>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
</TableRowComponent>
|
|
||||||
|
|
||||||
{expandedRow && (
|
{expandedRow && isExpanded && (
|
||||||
<AccordionContent asChild={true}>
|
<TableRowComponent
|
||||||
<TableRowComponent
|
data-row-id={row.id + "-expanded-row"}
|
||||||
data-row-id={row.id + "-expanded-row"}
|
minimal={minimal}
|
||||||
key={row.id + "-expanded-row"}
|
className={cn(
|
||||||
minimal={minimal}
|
onRowClick && "cursor-pointer relative",
|
||||||
className={cn(
|
rowClassName,
|
||||||
onRowClick && "cursor-pointer relative",
|
|
||||||
rowClassName,
|
|
||||||
)}
|
|
||||||
data-state={row.getIsSelected() && "selected"}
|
|
||||||
>
|
|
||||||
<TableDataUnstyledComponent
|
|
||||||
className={"w-full"}
|
|
||||||
colSpan={row.getVisibleCells().length}
|
|
||||||
>
|
|
||||||
{expandedRow}
|
|
||||||
</TableDataUnstyledComponent>
|
|
||||||
</TableRowComponent>
|
|
||||||
</AccordionContent>
|
|
||||||
)}
|
)}
|
||||||
</>
|
data-state={row.getIsSelected() && "selected"}
|
||||||
</AccordionItem>
|
>
|
||||||
);
|
<TableDataUnstyledComponent
|
||||||
|
className={"w-full"}
|
||||||
|
colSpan={row.getVisibleCells().length}
|
||||||
|
>
|
||||||
|
{expandedRow}
|
||||||
|
</TableDataUnstyledComponent>
|
||||||
|
</TableRowComponent>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
return renderRow
|
return renderRow
|
||||||
? renderRow(row.original, rowContent)
|
? renderRow(row.original, rowContent)
|
||||||
: rowContent;
|
: rowContent;
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<TableRowUnstyledComponent>
|
<TableRowUnstyledComponent>
|
||||||
<TableCellComponent
|
<TableCellComponent
|
||||||
@@ -614,8 +589,7 @@ export function DataTable<TData, TValue>({
|
|||||||
</TableCellComponent>
|
</TableCellComponent>
|
||||||
</TableRowUnstyledComponent>
|
</TableRowUnstyledComponent>
|
||||||
)}
|
)}
|
||||||
</TableBodyComponent>
|
</TableBodyComponent>
|
||||||
</Accordion>
|
|
||||||
</TableComponent>
|
</TableComponent>
|
||||||
)}
|
)}
|
||||||
</TableWrapper>
|
</TableWrapper>
|
||||||
|
|||||||
@@ -64,8 +64,16 @@ const Time = ({
|
|||||||
}
|
}
|
||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
|
const { ref, ...rootProps } = getRootProps();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"timescape w-full"} {...getRootProps()}>
|
<div
|
||||||
|
className={"timescape w-full"}
|
||||||
|
ref={(element) => {
|
||||||
|
ref(element);
|
||||||
|
}}
|
||||||
|
{...rootProps}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<input {...getInputProps("years")} />
|
<input {...getInputProps("years")} />
|
||||||
<span className={"separator"}>/</span>
|
<span className={"separator"}>/</span>
|
||||||
|
|||||||
@@ -19,40 +19,46 @@ function Calendar({
|
|||||||
showOutsideDays={showOutsideDays}
|
showOutsideDays={showOutsideDays}
|
||||||
className={cn("p-3", className)}
|
className={cn("p-3", className)}
|
||||||
classNames={{
|
classNames={{
|
||||||
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
months: "flex flex-col sm:flex-row space-y-4 sm:space-y-0 relative",
|
||||||
month: "space-y-4",
|
month: "space-y-4 pr-4 last:pr-0",
|
||||||
caption: "flex justify-center pt-1 relative items-center",
|
month_caption: "flex justify-center pt-1 relative items-center",
|
||||||
caption_label: "text-sm font-medium",
|
caption_label: "text-sm font-medium",
|
||||||
nav: "space-x-1 flex items-center",
|
nav: "space-x-1 flex items-center",
|
||||||
nav_button: cn(
|
button_previous: cn(
|
||||||
buttonVariants({ variant: "outline" }),
|
buttonVariants({ variant: "outline" }),
|
||||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-0 top-0 z-10",
|
||||||
),
|
),
|
||||||
nav_button_previous: "absolute left-1",
|
button_next: cn(
|
||||||
nav_button_next: "absolute right-1",
|
buttonVariants({ variant: "outline" }),
|
||||||
table: "w-full border-collapse space-y-1",
|
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-0 top-0 z-10",
|
||||||
head_row: "flex",
|
),
|
||||||
head_cell:
|
month_grid: "w-full border-collapse space-y-1",
|
||||||
|
weekdays: "flex",
|
||||||
|
weekday:
|
||||||
"text-neutral-500 rounded-md w-9 font-normal text-[0.8rem] dark:text-neutral-400",
|
"text-neutral-500 rounded-md w-9 font-normal text-[0.8rem] dark:text-neutral-400",
|
||||||
row: "flex w-full mt-2",
|
week: "flex w-full mt-2",
|
||||||
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-neutral-100/50 [&:has([aria-selected])]:bg-neutral-100 first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20 dark:[&:has([aria-selected].day-outside)]:bg-neutral-800/50 dark:[&:has([aria-selected])]:bg-neutral-800",
|
day: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-neutral-100/50 [&:has([aria-selected])]:bg-neutral-100 first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20 dark:[&:has([aria-selected].day-outside)]:bg-neutral-800/50 dark:[&:has([aria-selected])]:bg-neutral-800",
|
||||||
day: cn("h-9 w-9 p-0 font-normal aria-selected:opacity-100"),
|
day_button: cn("h-9 w-9 p-0 font-normal aria-selected:opacity-100"),
|
||||||
day_range_end: "day-range-end rounded-r-md",
|
range_end: "day-range-end rounded-r-md",
|
||||||
day_range_start: "day-range-start rounded-l-md",
|
range_start: "day-range-start rounded-l-md",
|
||||||
day_selected:
|
selected:
|
||||||
"bg-neutral-900 text-neutral-50 hover:bg-neutral-900 hover:text-neutral-50 focus:bg-neutral-900 focus:text-neutral-50 dark:bg-neutral-50 dark:text-neutral-900 dark:hover:bg-neutral-50 dark:hover:text-neutral-900 dark:focus:bg-neutral-50 dark:focus:text-neutral-900",
|
"bg-neutral-900 text-neutral-50 hover:bg-neutral-900 hover:text-neutral-50 focus:bg-neutral-900 focus:text-neutral-50 dark:bg-neutral-50 dark:text-neutral-900 dark:hover:bg-neutral-50 dark:hover:text-neutral-900 dark:focus:bg-neutral-50 dark:focus:text-neutral-900",
|
||||||
day_today: "text-neutral-900 dark:text-red-500",
|
today: "text-neutral-900 dark:text-red-500",
|
||||||
day_outside:
|
outside:
|
||||||
"day-outside text-neutral-500 opacity-50 aria-selected:bg-neutral-100/50 aria-selected:text-neutral-500 aria-selected:opacity-30 dark:text-neutral-400 dark:aria-selected:bg-neutral-800/50 dark:aria-selected:text-neutral-400",
|
"day-outside text-neutral-500 opacity-50 aria-selected:bg-neutral-100/50 aria-selected:text-neutral-500 aria-selected:opacity-30 dark:text-neutral-400 dark:aria-selected:bg-neutral-800/50 dark:aria-selected:text-neutral-400",
|
||||||
day_disabled: "text-neutral-500 opacity-50 dark:text-neutral-400",
|
disabled: "text-neutral-500 opacity-50 dark:text-neutral-400",
|
||||||
day_range_middle:
|
range_middle:
|
||||||
"aria-selected:bg-neutral-100 aria-selected:text-neutral-900 dark:aria-selected:bg-nb-gray-800 dark:aria-selected:text-neutral-50 rounded-none",
|
"aria-selected:bg-neutral-100 aria-selected:text-neutral-900 dark:aria-selected:bg-nb-gray-800 dark:aria-selected:text-neutral-50 rounded-none",
|
||||||
day_hidden: "invisible",
|
hidden: "invisible",
|
||||||
...classNames,
|
...classNames,
|
||||||
}}
|
}}
|
||||||
components={{
|
components={{
|
||||||
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
|
Chevron: ({ orientation }) =>
|
||||||
IconRight: () => <ChevronRight className="h-4 w-4" />,
|
orientation === "left" ? (
|
||||||
|
<ChevronLeft className="h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<ChevronRight className="h-4 w-4" />
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function AnalyticsProvider({ children }: Readonly<Props>) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (hjid && window._DATADOG_SYNTHETICS_BROWSER === undefined) {
|
if (hjid && window._DATADOG_SYNTHETICS_BROWSER === undefined) {
|
||||||
hotjar.initialize(hjid, 6);
|
hotjar.initialize({ id: hjid, sv: 6 });
|
||||||
}
|
}
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function DialogProvider({ children }: Props) {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
});
|
});
|
||||||
const [dialogOptions, setDialogOptions] = useState<DialogOptions>();
|
const [dialogOptions, setDialogOptions] = useState<DialogOptions>();
|
||||||
const fn = useRef<Function>();
|
const fn = useRef<Function>(undefined);
|
||||||
|
|
||||||
const confirm = useCallback((data: DialogOptions): Promise<boolean> => {
|
const confirm = useCallback((data: DialogOptions): Promise<boolean> => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import "react-loading-skeleton/dist/skeleton.css";
|
import "react-loading-skeleton/dist/skeleton.css";
|
||||||
import { netbirdTheme } from "@utils/theme";
|
|
||||||
import { Flowbite } from "flowbite-react";
|
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { type ThemeProviderProps } from "next-themes/dist/types";
|
import { type ThemeProviderProps } from "next-themes/dist/types";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@@ -26,11 +24,9 @@ export function GlobalThemeProvider({
|
|||||||
disableTransitionOnChange
|
disableTransitionOnChange
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<Flowbite theme={{ theme: netbirdTheme }}>
|
<SkeletonTheme baseColor={"#25282d"} highlightColor={"#33373e"}>
|
||||||
<SkeletonTheme baseColor={"#25282d"} highlightColor={"#33373e"}>
|
{children}
|
||||||
{children}
|
</SkeletonTheme>
|
||||||
</SkeletonTheme>
|
|
||||||
</Flowbite>
|
|
||||||
</NextThemesProvider>
|
</NextThemesProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { RefObject, useEffect, useRef, useState } from "react";
|
import { RefObject, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
export default function useIsVisible(ref: RefObject<HTMLElement>) {
|
export default function useIsVisible(ref: RefObject<HTMLElement | null>) {
|
||||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||||
const [isOnScreen, setIsOnScreen] = useState(false);
|
const [isOnScreen, setIsOnScreen] = useState(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
const usePrevious = <T>(value: T): T | undefined => {
|
const usePrevious = <T>(value: T): T | undefined => {
|
||||||
const ref = useRef<T>();
|
const ref = useRef<T>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ref.current = value;
|
ref.current = value;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default function AppLayout({
|
|||||||
<head>
|
<head>
|
||||||
<GoogleTagManagerHeadScript />
|
<GoogleTagManagerHeadScript />
|
||||||
</head>
|
</head>
|
||||||
<body className={cn(inter.className, "dark:bg-nb-gray bg-gray-50")}>
|
<body className={cn(inter.className)}>
|
||||||
<Suspense fallback={<FullScreenLoading />}>
|
<Suspense fallback={<FullScreenLoading />}>
|
||||||
<AnalyticsProvider>
|
<AnalyticsProvider>
|
||||||
<DialogProvider>
|
<DialogProvider>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type Props = {
|
|||||||
version?: string;
|
version?: string;
|
||||||
versionText?: string;
|
versionText?: string;
|
||||||
versionList?: SelectOption[];
|
versionList?: SelectOption[];
|
||||||
icon: React.FunctionComponent<{ size: number }>;
|
icon: (props: { size: number }) => React.ReactElement;
|
||||||
os: string;
|
os: string;
|
||||||
};
|
};
|
||||||
export const PostureCheckOperatingSystemInfo = ({
|
export const PostureCheckOperatingSystemInfo = ({
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class RDPCertificateHandler implements CertificateHandler {
|
|||||||
* Calculate SHA-256 fingerprint of certificate
|
* Calculate SHA-256 fingerprint of certificate
|
||||||
*/
|
*/
|
||||||
async calculateFingerprint(certBytes: Uint8Array): Promise<string> {
|
async calculateFingerprint(certBytes: Uint8Array): Promise<string> {
|
||||||
const hashBuffer = await crypto.subtle.digest('SHA-256', certBytes);
|
const hashBuffer = await crypto.subtle.digest('SHA-256', certBytes as Uint8Array<ArrayBuffer>);
|
||||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
return hashArray
|
return hashArray
|
||||||
.map(b => b.toString(16).padStart(2, '0'))
|
.map(b => b.toString(16).padStart(2, '0'))
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export const useRDPCertificateHandler = () => {
|
|||||||
const calculateFingerprint = useCallback(
|
const calculateFingerprint = useCallback(
|
||||||
async (certBytes: Uint8Array): Promise<string> => {
|
async (certBytes: Uint8Array): Promise<string> => {
|
||||||
try {
|
try {
|
||||||
const hashBuffer = await crypto.subtle.digest("SHA-256", certBytes);
|
const hashBuffer = await crypto.subtle.digest("SHA-256", certBytes as Uint8Array<ArrayBuffer>);
|
||||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
const fingerprint = hashArray
|
const fingerprint = hashArray
|
||||||
.map((b) => b.toString(16).padStart(2, "0"))
|
.map((b) => b.toString(16).padStart(2, "0"))
|
||||||
|
|||||||
@@ -191,16 +191,6 @@ export default function GroupsSettings({ account }: Props) {
|
|||||||
disabled={!permission.settings.update}
|
disabled={!permission.settings.update}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Callout variant={"info"} className={""}>
|
|
||||||
Looking to view and manage your groups? You can find group
|
|
||||||
management under{" "}
|
|
||||||
<InlineButtonLink
|
|
||||||
onClick={() => router.push("/groups")}
|
|
||||||
variant={"dashed"}
|
|
||||||
>
|
|
||||||
{`Access Control › Groups`}
|
|
||||||
</InlineButtonLink>
|
|
||||||
</Callout>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{(!isNetBirdHosted() || isLocalDev()) && (
|
{(!isNetBirdHosted() || isLocalDev()) && (
|
||||||
@@ -323,6 +313,17 @@ export default function GroupsSettings({ account }: Props) {
|
|||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Callout variant={"info"} className={"mt-6"}>
|
||||||
|
Looking to view and manage your groups? You can find group management
|
||||||
|
under{" "}
|
||||||
|
<InlineButtonLink
|
||||||
|
onClick={() => router.push("/groups")}
|
||||||
|
variant={"dashed"}
|
||||||
|
>
|
||||||
|
{`Access Control › Groups`}
|
||||||
|
</InlineButtonLink>
|
||||||
|
</Callout>
|
||||||
</div>
|
</div>
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function useNetBirdFetch(ignoreError: boolean = false): {
|
|||||||
const handleErrors = useApiErrorHandling(ignoreError);
|
const handleErrors = useApiErrorHandling(ignoreError);
|
||||||
|
|
||||||
const isTokenExpired = async () => {
|
const isTokenExpired = async () => {
|
||||||
let attempts = 20;
|
let attempts = 4;
|
||||||
while (isExpired(token) && attempts > 0) {
|
while (isExpired(token) && attempts > 0) {
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
attempts = attempts - 1;
|
attempts = attempts - 1;
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { CustomFlowbiteTheme } from "flowbite-react";
|
|
||||||
|
|
||||||
export const netbirdTheme: CustomFlowbiteTheme = {
|
|
||||||
navbar: {
|
|
||||||
root: {
|
|
||||||
base: "bg-white px-2 py-4 dark:border-gray-700 dark:bg-nb-gray/50 backdrop-blur-lg bg-gray-50 sm:px-6",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dropdown: {
|
|
||||||
floating: {
|
|
||||||
divider: "my-1 h-px bg-gray-100 dark:bg-zinc-800",
|
|
||||||
item: {
|
|
||||||
base: "flex items-center justify-start py-2 px-4 text-sm text-gray-700 cursor-pointer w-full hover:bg-gray-100 focus:bg-gray-100 dark:text-gray-200 dark:hover:bg-zinc-800 focus:outline-none dark:hover:text-white dark:focus:bg-zinc-800 dark:focus:text-white",
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
auto: "border border-gray-200 bg-white text-gray-900 dark:border-zinc-800/50 dark:bg-zinc-900 dark:text-white",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,14 +1,107 @@
|
|||||||
import type { Config } from "tailwindcss";
|
import type { Config } from "tailwindcss";
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
content: [
|
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
|
||||||
"./node_modules/flowbite-react/**/*.js",
|
|
||||||
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
|
||||||
],
|
|
||||||
darkMode: "class",
|
darkMode: "class",
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
|
gray: {
|
||||||
|
50: "#F9FAFB",
|
||||||
|
100: "#F3F4F6",
|
||||||
|
200: "#E5E7EB",
|
||||||
|
300: "#D1D5DB",
|
||||||
|
400: "#9CA3AF",
|
||||||
|
500: "#6B7280",
|
||||||
|
600: "#4B5563",
|
||||||
|
700: "#374151",
|
||||||
|
800: "#1F2937",
|
||||||
|
900: "#111827",
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
50: "#FDF2F2",
|
||||||
|
100: "#FDE8E8",
|
||||||
|
200: "#FBD5D5",
|
||||||
|
300: "#F8B4B4",
|
||||||
|
400: "#F98080",
|
||||||
|
500: "#F05252",
|
||||||
|
600: "#E02424",
|
||||||
|
700: "#C81E1E",
|
||||||
|
800: "#9B1C1C",
|
||||||
|
900: "#771D1D",
|
||||||
|
},
|
||||||
|
yellow: {
|
||||||
|
50: "#FDFDEA",
|
||||||
|
100: "#FDF6B2",
|
||||||
|
200: "#FCE96A",
|
||||||
|
300: "#FACA15",
|
||||||
|
400: "#E3A008",
|
||||||
|
500: "#C27803",
|
||||||
|
600: "#9F580A",
|
||||||
|
700: "#8E4B10",
|
||||||
|
800: "#723B13",
|
||||||
|
900: "#633112",
|
||||||
|
},
|
||||||
|
green: {
|
||||||
|
50: "#F3FAF7",
|
||||||
|
100: "#DEF7EC",
|
||||||
|
200: "#BCF0DA",
|
||||||
|
300: "#84E1BC",
|
||||||
|
400: "#31C48D",
|
||||||
|
500: "#0E9F6E",
|
||||||
|
600: "#057A55",
|
||||||
|
700: "#046C4E",
|
||||||
|
800: "#03543F",
|
||||||
|
900: "#014737",
|
||||||
|
},
|
||||||
|
blue: {
|
||||||
|
50: "#EBF5FF",
|
||||||
|
100: "#E1EFFE",
|
||||||
|
200: "#C3DDFD",
|
||||||
|
300: "#A4CAFE",
|
||||||
|
400: "#76A9FA",
|
||||||
|
500: "#3F83F8",
|
||||||
|
600: "#1C64F2",
|
||||||
|
700: "#1A56DB",
|
||||||
|
800: "#1E429F",
|
||||||
|
900: "#233876",
|
||||||
|
},
|
||||||
|
indigo: {
|
||||||
|
50: "#F0F5FF",
|
||||||
|
100: "#E5EDFF",
|
||||||
|
200: "#CDDBFE",
|
||||||
|
300: "#B4C6FC",
|
||||||
|
400: "#8DA2FB",
|
||||||
|
500: "#6875F5",
|
||||||
|
600: "#5850EC",
|
||||||
|
700: "#5145CD",
|
||||||
|
800: "#42389D",
|
||||||
|
900: "#362F78",
|
||||||
|
},
|
||||||
|
purple: {
|
||||||
|
50: "#F6F5FF",
|
||||||
|
100: "#EDEBFE",
|
||||||
|
200: "#DCD7FE",
|
||||||
|
300: "#CABFFD",
|
||||||
|
400: "#AC94FA",
|
||||||
|
500: "#9061F9",
|
||||||
|
600: "#7E3AF2",
|
||||||
|
700: "#6C2BD9",
|
||||||
|
800: "#5521B5",
|
||||||
|
900: "#4A1D96",
|
||||||
|
},
|
||||||
|
pink: {
|
||||||
|
50: "#FDF2F8",
|
||||||
|
100: "#FCE8F3",
|
||||||
|
200: "#FAD1E8",
|
||||||
|
300: "#F8B4D9",
|
||||||
|
400: "#F17EB8",
|
||||||
|
500: "#E74694",
|
||||||
|
600: "#D61F69",
|
||||||
|
700: "#BF125D",
|
||||||
|
800: "#99154B",
|
||||||
|
900: "#751A3D",
|
||||||
|
},
|
||||||
"nb-gray": {
|
"nb-gray": {
|
||||||
DEFAULT: "#181A1D",
|
DEFAULT: "#181A1D",
|
||||||
"50": "#f4f6f7",
|
"50": "#f4f6f7",
|
||||||
@@ -33,6 +126,7 @@ const config: Config = {
|
|||||||
"950": "#181a1d",
|
"950": "#181a1d",
|
||||||
"960": "#15171a",
|
"960": "#15171a",
|
||||||
},
|
},
|
||||||
|
|
||||||
netbird: {
|
netbird: {
|
||||||
DEFAULT: "#f68330",
|
DEFAULT: "#f68330",
|
||||||
"50": "#fff6ed",
|
"50": "#fff6ed",
|
||||||
@@ -82,6 +176,6 @@ const config: Config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [require("flowbite/plugin"), require("tailwindcss-animate")],
|
plugins: [require("tailwindcss-animate")],
|
||||||
};
|
};
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
@@ -52,10 +52,11 @@
|
|||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
"src/**/*.tsx",
|
"src/**/*.tsx",
|
||||||
".next/types/**/*.ts"
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"node_modules/@axa-fr/**/*",
|
"node_modules/@axa-fr/**/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user