mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
Merge pull request #29 from prowler-cloud/PRWLR-4141-Providers-Page-Add-Providers-modal-2
Providers page add providers modal -
This commit is contained in:
@@ -20,7 +20,6 @@ export const getProvider = async () => {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const addProvider = async (formData: FormData) => {
|
||||
const keyServer = process.env.LOCAL_SERVER_URL;
|
||||
|
||||
@@ -57,7 +56,6 @@ export const addProvider = async (formData: FormData) => {
|
||||
}
|
||||
revalidatePath("/providers");
|
||||
};
|
||||
|
||||
export const checkConnectionProvider = async (formData: FormData) => {
|
||||
const keyServer = process.env.LOCAL_SERVER_URL;
|
||||
|
||||
@@ -82,7 +80,6 @@ export const checkConnectionProvider = async (formData: FormData) => {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteProvider = async (formData: FormData) => {
|
||||
const keyServer = process.env.LOCAL_SERVER_URL;
|
||||
|
||||
|
||||
@@ -3,38 +3,21 @@ import React, { Suspense } from "react";
|
||||
|
||||
import { getProvider } from "@/actions";
|
||||
import {
|
||||
AddProvider,
|
||||
AddProviderModal,
|
||||
ColumnsProviders,
|
||||
DataTable,
|
||||
Header,
|
||||
ModalWrap,
|
||||
SkeletonTableProvider,
|
||||
} from "@/components";
|
||||
|
||||
export default async function Providers() {
|
||||
const onSave = async () => {
|
||||
"use server";
|
||||
// event we want to pass down, ex. console.log("### hello");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header title="Providers" icon="fluent:cloud-sync-24-regular" />
|
||||
<Spacer />
|
||||
<div className="flex flex-col items-end w-full">
|
||||
<div className="flex space-x-6">
|
||||
<AddProvider />
|
||||
<ModalWrap
|
||||
modalTitle="Modal Title"
|
||||
modalBody={
|
||||
<>
|
||||
<p>Modal body content</p>
|
||||
</>
|
||||
}
|
||||
actionButtonLabel="Save"
|
||||
onAction={onSave}
|
||||
openButtonLabel="Add Cloud Accounts"
|
||||
/>
|
||||
<AddProviderModal />
|
||||
</div>
|
||||
<Spacer y={6} />
|
||||
<Suspense fallback={<SkeletonTableProvider />}>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
export * from "./findings/ColumnsFindings";
|
||||
export * from "./findings/SkeletonTableFindings";
|
||||
export * from "./providers/AddProvider";
|
||||
export * from "./providers/AddProviderModal";
|
||||
export * from "./providers/ButtonAddProvider";
|
||||
export * from "./providers/ButtonCheckConnectionProvider";
|
||||
export * from "./providers/ButtonDeleteProvider";
|
||||
export * from "./providers/CheckConnectionProvider";
|
||||
export * from "./providers/CustomRadioProvider";
|
||||
export * from "./providers/DateWithTime";
|
||||
export * from "./providers/ProviderInfo";
|
||||
export * from "./providers/ScanStatus";
|
||||
@@ -12,6 +14,7 @@ export * from "./providers/table/ColumnsProviders";
|
||||
export * from "./providers/table/DataTable";
|
||||
export * from "./providers/table/SkeletonTableProvider";
|
||||
export * from "./ui/alert/Alert";
|
||||
export * from "./ui/dialog/Dialog";
|
||||
export * from "./ui/header/Header";
|
||||
export * from "./ui/modal";
|
||||
export * from "./ui/sidebar";
|
||||
|
||||
@@ -23,7 +23,7 @@ export const AddProvider = () => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Ups! Something went wrong",
|
||||
description: errorMessage
|
||||
description: errorMessage,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
"use client";
|
||||
|
||||
import { Button, Input } from "@nextui-org/react";
|
||||
import { useRef, useState } from "react";
|
||||
|
||||
import { addProvider } from "@/actions";
|
||||
import {
|
||||
ButtonAddProvider,
|
||||
CustomRadioProvider,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
useToast,
|
||||
} from "@/components";
|
||||
|
||||
export const AddProviderModal = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const ref = useRef<HTMLFormElement>(null);
|
||||
const { toast } = useToast();
|
||||
|
||||
async function clientAction(formData: FormData) {
|
||||
// reset the form
|
||||
ref.current?.reset();
|
||||
// client-side validation
|
||||
const data = await addProvider(formData);
|
||||
if (data?.errors) {
|
||||
data.errors.forEach((error: { detail: string }) => {
|
||||
const errorMessage = `${error.detail}`;
|
||||
// show error
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Ups! Something went wrong",
|
||||
description: errorMessage,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
title: "Success!",
|
||||
description: "The provider was added successfully.",
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="ghost">Add Cloud Account</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="flex flex-col sm:max-w-md md:max-w-4xl">
|
||||
<DialogHeader className="mb-6 space-y-3">
|
||||
<DialogTitle className="text-2xl text-center">
|
||||
Add cloud account
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-md">
|
||||
You must manually deploy a new read-only IAM role for each account
|
||||
you want to add. The following links will provide detailed
|
||||
instructions how to do this:
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<form
|
||||
ref={ref}
|
||||
action={clientAction}
|
||||
onSubmit={() => setOpen(false)}
|
||||
className="grid sm:grid-cols-2 gap-6"
|
||||
>
|
||||
<div className="col-span-1">
|
||||
<CustomRadioProvider />
|
||||
</div>
|
||||
<div className="col-span-1 flex flex-col gap-y-2 my-auto">
|
||||
<Input
|
||||
type="text"
|
||||
name="id"
|
||||
label="Provider ID"
|
||||
labelPlacement="outside"
|
||||
placeholder="Provider ID"
|
||||
className="w-full rounded-sm"
|
||||
aria-label="Enter Provider ID"
|
||||
/>
|
||||
<Input
|
||||
type="text"
|
||||
name="alias"
|
||||
label="Alias"
|
||||
labelPlacement="outside"
|
||||
placeholder="alias"
|
||||
className="w-full rounded-sm"
|
||||
aria-label="Enter Provider alias"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 flex justify-center mt-4">
|
||||
<ButtonAddProvider />
|
||||
</div>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
|
||||
import { UseRadioProps } from "@nextui-org/radio/dist/use-radio";
|
||||
import { cn, RadioGroup, useRadio, VisuallyHidden } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
import { AwsProvider, AzureProvider, GoogleCloudProvider } from "../icons";
|
||||
|
||||
interface CustomRadioProps extends UseRadioProps {
|
||||
description?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const CustomRadio: React.FC<CustomRadioProps> = (props) => {
|
||||
const {
|
||||
Component,
|
||||
children,
|
||||
description,
|
||||
getBaseProps,
|
||||
getWrapperProps,
|
||||
getInputProps,
|
||||
getLabelProps,
|
||||
getLabelWrapperProps,
|
||||
getControlProps,
|
||||
} = useRadio(props);
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...getBaseProps()}
|
||||
className={cn(
|
||||
"group inline-flex items-center hover:opacity-70 active:opacity-50 justify-between flex-row-reverse tap-highlight-transparent",
|
||||
"max-w-full cursor-pointer border-2 border-default rounded-lg gap-4 p-4",
|
||||
"data-[selected=true]:border-primary",
|
||||
)}
|
||||
>
|
||||
<VisuallyHidden>
|
||||
<input {...getInputProps()} />
|
||||
</VisuallyHidden>
|
||||
<span {...getWrapperProps()}>
|
||||
<span {...getControlProps()} />
|
||||
</span>
|
||||
<div {...getLabelWrapperProps()}>
|
||||
{children && <span {...getLabelProps()}>{children}</span>}
|
||||
{description && (
|
||||
<span className="text-small text-foreground opacity-70">
|
||||
{description}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
export const CustomRadioProvider = () => {
|
||||
return (
|
||||
<RadioGroup label="Select one provider" name="provider">
|
||||
<CustomRadio description="Amazon Web Services" value="aws">
|
||||
<div className="flex items-center">
|
||||
<AwsProvider size={26} />
|
||||
<span className="ml-2">AWS</span>
|
||||
</div>
|
||||
</CustomRadio>
|
||||
<CustomRadio description="Google Cloud Platform" value="gcp">
|
||||
<div className="flex items-center">
|
||||
<GoogleCloudProvider size={26} />
|
||||
<span className="ml-2">GCP</span>
|
||||
</div>
|
||||
</CustomRadio>
|
||||
<CustomRadio description="Microsoft Azure" value="azure">
|
||||
<div className="flex items-center">
|
||||
<AzureProvider size={26} />
|
||||
<span className="ml-2">Azure</span>
|
||||
</div>
|
||||
</CustomRadio>
|
||||
</RadioGroup>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
"use client";
|
||||
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { X } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Dialog = DialogPrimitive.Root;
|
||||
|
||||
const DialogTrigger = DialogPrimitive.Trigger;
|
||||
|
||||
const DialogPortal = DialogPrimitive.Portal;
|
||||
|
||||
const DialogClose = DialogPrimitive.Close;
|
||||
|
||||
const DialogOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||
|
||||
const DialogContent = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-slate-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg dark:border-slate-800 dark:bg-slate-950",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 data-[state=open]:text-slate-500 dark:ring-offset-slate-950 dark:focus:ring-slate-300 dark:data-[state=open]:bg-slate-800 dark:data-[state=open]:text-slate-400">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
));
|
||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||
|
||||
const DialogHeader = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DialogHeader.displayName = "DialogHeader";
|
||||
|
||||
const DialogFooter = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DialogFooter.displayName = "DialogFooter";
|
||||
|
||||
const DialogTitle = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
||||
|
||||
const DialogDescription = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn("text-sm text-slate-500 dark:text-slate-400", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
};
|
||||
@@ -6,9 +6,11 @@ import {
|
||||
export const fontSans = FontSans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
preload: false,
|
||||
});
|
||||
|
||||
export const fontMono = FontMono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-mono",
|
||||
preload: false,
|
||||
});
|
||||
|
||||
@@ -4,67 +4,4 @@ export const siteConfig = {
|
||||
name: "Prowler",
|
||||
description:
|
||||
"The most comprehensive, free tool for AWS security. ProwlerPro is trusted by leading organizations to make cloud security effortless.",
|
||||
navItems: [
|
||||
{
|
||||
label: "Home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "Docs",
|
||||
href: "/docs",
|
||||
},
|
||||
{
|
||||
label: "Pricing",
|
||||
href: "/pricing",
|
||||
},
|
||||
{
|
||||
label: "Blog",
|
||||
href: "/blog",
|
||||
},
|
||||
{
|
||||
label: "About",
|
||||
href: "/about",
|
||||
},
|
||||
],
|
||||
navMenuItems: [
|
||||
{
|
||||
label: "Profile",
|
||||
href: "/profile",
|
||||
},
|
||||
{
|
||||
label: "Dashboard",
|
||||
href: "/dashboard",
|
||||
},
|
||||
{
|
||||
label: "Projects",
|
||||
href: "/projects",
|
||||
},
|
||||
{
|
||||
label: "Team",
|
||||
href: "/team",
|
||||
},
|
||||
{
|
||||
label: "Calendar",
|
||||
href: "/calendar",
|
||||
},
|
||||
{
|
||||
label: "Settings",
|
||||
href: "/settings",
|
||||
},
|
||||
{
|
||||
label: "Help & Feedback",
|
||||
href: "/help-feedback",
|
||||
},
|
||||
{
|
||||
label: "Logout",
|
||||
href: "/logout",
|
||||
},
|
||||
],
|
||||
links: {
|
||||
github: "https://github.com/nextui-org/nextui",
|
||||
twitter: "https://twitter.com/getnextui",
|
||||
docs: "https://nextui.org",
|
||||
discord: "https://discord.gg/9b6yyZKmH4",
|
||||
sponsor: "https://patreon.com/jrgarciadev",
|
||||
},
|
||||
};
|
||||
|
||||
Generated
+126
@@ -11,6 +11,7 @@
|
||||
"@nextui-org/react": "^2.4.2",
|
||||
"@nextui-org/system": "2.2.1",
|
||||
"@nextui-org/theme": "2.2.5",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-toast": "^1.2.1",
|
||||
"@react-aria/ssr": "3.9.4",
|
||||
@@ -2649,6 +2650,65 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dialog": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz",
|
||||
"integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.0",
|
||||
"@radix-ui/react-focus-guards": "1.1.0",
|
||||
"@radix-ui/react-focus-scope": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-portal": "1.1.1",
|
||||
"@radix-ui/react-presence": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-slot": "1.1.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"aria-hidden": "^1.1.1",
|
||||
"react-remove-scroll": "2.5.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": {
|
||||
"version": "2.5.7",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
|
||||
"integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
|
||||
"dependencies": {
|
||||
"react-remove-scroll-bar": "^2.3.4",
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"tslib": "^2.1.0",
|
||||
"use-callback-ref": "^1.3.0",
|
||||
"use-sidecar": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dismissable-layer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
|
||||
@@ -2675,6 +2735,44 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-focus-guards": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
|
||||
"integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-focus-scope": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
|
||||
"integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-icons": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
|
||||
@@ -2683,6 +2781,23 @@
|
||||
"react": "^16.x || ^17.x || ^18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-id": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
|
||||
"integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-portal": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
|
||||
@@ -4478,6 +4593,17 @@
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
|
||||
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"@nextui-org/react": "^2.4.2",
|
||||
"@nextui-org/system": "2.2.1",
|
||||
"@nextui-org/theme": "2.2.5",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-toast": "^1.2.1",
|
||||
"@react-aria/ssr": "3.9.4",
|
||||
|
||||
Reference in New Issue
Block a user