mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-31 15:54:24 +00:00
feat: upgrade to React 19, Next.js 15, React Compiler, HeroUI and Tailwind 4 (#8748)
Co-authored-by: Alan Buscaglia <alanbuscaglia@MacBook-Pro.local> Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com> Co-authored-by: César Arroba <cesar@prowler.com> Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com>
This commit is contained in:
261 files changed
+6339
-6126
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { Modal, ModalBody, ModalContent, ModalHeader } from "@nextui-org/react";
|
||||
import { Modal, ModalBody, ModalContent, ModalHeader } from "@heroui/modal";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
interface CustomAlertModalProps {
|
||||
|
||||
@@ -18,9 +18,9 @@ export const CustomBanner = ({
|
||||
buttonLink = "/",
|
||||
}: CustomBannerProps) => {
|
||||
return (
|
||||
<div className="flex items-center justify-start rounded-lg border-1 border-system-warning-light px-4 py-6 shadow-box dark:bg-prowler-blue-400">
|
||||
<div className="border-system-warning-light shadow-box dark:bg-prowler-blue-400 flex items-center justify-start rounded-lg border px-4 py-6">
|
||||
<div className="flex w-full flex-col items-start gap-6 md:flex-row md:items-center md:justify-between md:gap-8">
|
||||
<div className="flex flex-col space-y-3">
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center justify-start gap-3">
|
||||
<InfoIcon className="h-6 w-6 text-gray-800 dark:text-white" />
|
||||
<h2 className="text-lg font-bold text-gray-800 dark:text-white">
|
||||
@@ -29,7 +29,7 @@ export const CustomBanner = ({
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">{message}</p>
|
||||
</div>
|
||||
<div className="w-full md:w-auto md:flex-shrink-0">
|
||||
<div className="w-full md:w-auto md:shrink-0">
|
||||
<CustomButton
|
||||
asLink={buttonLink}
|
||||
className="w-full justify-center md:w-fit"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Card, CardBody, CardHeader, Divider } from "@nextui-org/react";
|
||||
import { CardProps as NextUICardProps } from "@nextui-org/react";
|
||||
import type { CardProps as NextUICardProps } from "@heroui/card";
|
||||
import { Card, CardBody, CardHeader } from "@heroui/card";
|
||||
import { Divider } from "@heroui/divider";
|
||||
import React from "react";
|
||||
interface CustomBoxProps {
|
||||
children: React.ReactNode;
|
||||
@@ -29,7 +30,7 @@ export const CustomBox = ({
|
||||
<Divider />
|
||||
</>
|
||||
)}
|
||||
<CardBody className="px-3 pb-4 pt-3">{children}</CardBody>
|
||||
<CardBody className="px-3 pt-3 pb-4">{children}</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button, CircularProgress } from "@nextui-org/react";
|
||||
import { Button } from "@heroui/button";
|
||||
import { CircularProgress } from "@heroui/progress";
|
||||
import type { PressEvent } from "@react-types/shared";
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
Divider,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
ScrollShadow,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@heroui/button";
|
||||
import { Checkbox, CheckboxGroup } from "@heroui/checkbox";
|
||||
import { Divider } from "@heroui/divider";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@heroui/popover";
|
||||
import { ScrollShadow } from "@heroui/scroll-shadow";
|
||||
import { ChevronDown, X } from "lucide-react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import React, {
|
||||
@@ -221,7 +216,7 @@ export const CustomDropdownFilter = ({
|
||||
>
|
||||
<PopoverTrigger>
|
||||
<Button
|
||||
className="border-input hover:bg-accent hover:text-accent-foreground inline-flex h-auto min-h-10 items-center justify-between whitespace-nowrap rounded-md border border-dashed bg-background px-3 py-2 text-xs font-medium shadow-sm transition-colors focus-visible:outline-none disabled:opacity-50 dark:bg-prowler-blue-800"
|
||||
className="border-input hover:bg-accent hover:text-accent-foreground bg-background dark:bg-prowler-blue-800 inline-flex h-auto min-h-10 items-center justify-between rounded-md border px-3 py-2 text-xs font-medium whitespace-nowrap shadow-sm transition-colors focus-visible:outline-none disabled:opacity-50"
|
||||
endContent={
|
||||
<ChevronDown
|
||||
className={`h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
|
||||
@@ -231,26 +226,23 @@ export const CustomDropdownFilter = ({
|
||||
variant="flat"
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 items-center gap-2">
|
||||
<span className="flex-shrink-0 text-small">
|
||||
<span className="text-small shrink-0">
|
||||
{filter?.labelCheckboxGroup}
|
||||
</span>
|
||||
|
||||
{selectedValues.length > 0 && (
|
||||
<>
|
||||
<Divider
|
||||
orientation="vertical"
|
||||
className="h-4 flex-shrink-0"
|
||||
/>
|
||||
<div className="flex min-w-0 flex-shrink items-center">
|
||||
<Divider orientation="vertical" className="h-4 shrink-0" />
|
||||
<div className="flex min-w-0 shrink items-center">
|
||||
{selectedValues.length <= 2 ? (
|
||||
<span
|
||||
className="max-w-32 truncate text-xs text-default-500"
|
||||
className="text-default-500 max-w-32 truncate text-xs"
|
||||
title={selectedValues.map(getDisplayLabel).join(", ")}
|
||||
>
|
||||
{selectedValues.map(getDisplayLabel).join(", ")}
|
||||
</span>
|
||||
) : (
|
||||
<span className="truncate text-xs text-default-500">
|
||||
<span className="text-default-500 truncate text-xs">
|
||||
{isAllSelected
|
||||
? "All selected"
|
||||
: `${selectedValues.length} selected`}
|
||||
@@ -258,7 +250,7 @@ export const CustomDropdownFilter = ({
|
||||
)}
|
||||
<div
|
||||
onClick={handleClearAll}
|
||||
className="ml-1 flex h-4 w-4 flex-shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors hover:bg-default-200"
|
||||
className="hover:bg-default-200 ml-1 flex h-4 w-4 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors"
|
||||
aria-label="Clear selection"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
@@ -269,7 +261,7 @@ export const CustomDropdownFilter = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<X className="h-3 w-3 text-default-400 hover:text-default-600" />
|
||||
<X className="text-default-400 hover:text-default-600 h-3 w-3" />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
@@ -277,7 +269,7 @@ export const CustomDropdownFilter = ({
|
||||
</div>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto min-w-80 dark:bg-prowler-blue-800">
|
||||
<PopoverContent className="dark:bg-prowler-blue-800 w-auto min-w-80">
|
||||
<div className="flex w-full flex-col gap-4 p-2">
|
||||
<CheckboxGroup
|
||||
color="default"
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
CheckboxGroup,
|
||||
Divider,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
ScrollShadow,
|
||||
} from "@nextui-org/react";
|
||||
import { Button } from "@heroui/button";
|
||||
import { Checkbox, CheckboxGroup } from "@heroui/checkbox";
|
||||
import { Divider } from "@heroui/divider";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@heroui/popover";
|
||||
import { ScrollShadow } from "@heroui/scroll-shadow";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { PlusCircleIcon } from "@/components/icons";
|
||||
@@ -81,14 +76,14 @@ export const CustomDropdownSelection: React.FC<
|
||||
<Popover backdrop="transparent" placement="bottom-start">
|
||||
<PopoverTrigger>
|
||||
<Button
|
||||
className="border-input hover:bg-accent hover:text-accent-foreground inline-flex h-10 items-center justify-center whitespace-nowrap rounded-md border border-dashed bg-background px-3 text-xs font-medium shadow-sm transition-colors focus-visible:outline-none disabled:opacity-50 dark:bg-prowler-blue-800"
|
||||
className="border-input hover:bg-accent hover:text-accent-foreground bg-background dark:bg-prowler-blue-800 inline-flex h-10 items-center justify-center rounded-md border border-dashed px-3 text-xs font-medium whitespace-nowrap shadow-sm transition-colors focus-visible:outline-none disabled:opacity-50"
|
||||
startContent={<PlusCircleIcon size={16} />}
|
||||
size="md"
|
||||
>
|
||||
<h3 className="text-small">{label}</h3>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-80 dark:bg-prowler-blue-800">
|
||||
<PopoverContent className="dark:bg-prowler-blue-800 w-80">
|
||||
<div className="flex w-full flex-col gap-6 p-2">
|
||||
<CheckboxGroup
|
||||
color="default"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Input } from "@heroui/input";
|
||||
import { Icon } from "@iconify/react";
|
||||
import { Input } from "@nextui-org/react";
|
||||
import React, { useState } from "react";
|
||||
import { Control, FieldPath, FieldValues } from "react-hook-form";
|
||||
|
||||
@@ -79,7 +79,7 @@ export const CustomInput = <T extends FieldValues>({
|
||||
const endContent = (password || confirmPassword) && (
|
||||
<button type="button" onClick={toggleVisibility}>
|
||||
<Icon
|
||||
className="pointer-events-none text-2xl text-default-400"
|
||||
className="text-default-400 pointer-events-none text-2xl"
|
||||
icon={
|
||||
(password && isPasswordVisible) ||
|
||||
(confirmPassword && isConfirmPasswordVisible)
|
||||
@@ -101,7 +101,7 @@ export const CustomInput = <T extends FieldValues>({
|
||||
id={name}
|
||||
classNames={{
|
||||
label:
|
||||
"tracking-tight font-light !text-default-500 text-xs !z-0",
|
||||
"tracking-tight font-light !text-default-500 text-xs z-0!",
|
||||
input: "text-default-500 text-small",
|
||||
}}
|
||||
isRequired={inputIsRequired}
|
||||
@@ -117,10 +117,11 @@ export const CustomInput = <T extends FieldValues>({
|
||||
isDisabled={isDisabled}
|
||||
isReadOnly={isReadOnly}
|
||||
{...field}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormControl>
|
||||
{showFormMessage && (
|
||||
<FormMessage className="max-w-full text-xs text-system-error dark:text-system-error" />
|
||||
<FormMessage className="text-system-error dark:text-system-error max-w-full text-xs" />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -34,7 +34,7 @@ export const CustomLink = React.forwardRef<HTMLAnchorElement, CustomLinkProps>(
|
||||
href={href}
|
||||
scroll={scroll}
|
||||
className={cn(
|
||||
`text-${size} text-nowrap break-all font-medium text-primary decoration-1 hover:underline`,
|
||||
`text-${size} text-primary font-medium text-nowrap break-all decoration-1 hover:underline`,
|
||||
className,
|
||||
)}
|
||||
aria-label={ariaLabel}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { cn, useRadio, VisuallyHidden } from "@nextui-org/react";
|
||||
import { useRadio } from "@heroui/radio";
|
||||
import { cn } from "@heroui/theme";
|
||||
import { VisuallyHidden } from "@react-aria/visually-hidden";
|
||||
import React from "react";
|
||||
|
||||
interface CustomRadioProps {
|
||||
@@ -24,9 +26,9 @@ export const CustomRadio: React.FC<CustomRadioProps> = (props) => {
|
||||
<Component
|
||||
{...getBaseProps()}
|
||||
className={cn(
|
||||
"group inline-flex flex-row-reverse items-center justify-between tap-highlight-transparent hover:opacity-70 active:opacity-50",
|
||||
"max-w-full cursor-pointer gap-4 rounded-lg border-2 border-default p-4",
|
||||
"w-full hover:border-action data-[selected=true]:border-action",
|
||||
"group tap-highlight-transparent inline-flex flex-row-reverse items-center justify-between hover:opacity-70 active:opacity-50",
|
||||
"border-default max-w-full cursor-pointer gap-4 rounded-lg border-2 p-4",
|
||||
"hover:border-action data-[selected=true]:border-action w-full",
|
||||
)}
|
||||
>
|
||||
<VisuallyHidden>
|
||||
|
||||
@@ -9,9 +9,9 @@ export const CustomSection = ({
|
||||
children,
|
||||
action,
|
||||
}: CustomSectionProps) => (
|
||||
<div className="flex flex-col gap-4 rounded-lg p-4 shadow dark:bg-prowler-blue-400">
|
||||
<div className="dark:bg-prowler-blue-400 flex flex-col gap-4 rounded-lg p-4 shadow">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-md font-medium text-gray-800 dark:text-prowler-theme-pale/90">
|
||||
<h3 className="text-md dark:text-prowler-theme-pale/90 font-medium text-gray-800">
|
||||
{title}
|
||||
</h3>
|
||||
{action && <div>{action}</div>}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { Input } from "@nextui-org/react";
|
||||
import { Input } from "@heroui/input";
|
||||
import React from "react";
|
||||
|
||||
interface CustomServerInputProps {
|
||||
@@ -49,7 +49,7 @@ export const CustomServerInput = ({
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
classNames={{
|
||||
label: "tracking-tight font-light !text-default-500 text-xs !z-0",
|
||||
label: "tracking-tight font-light !text-default-500 text-xs z-0!",
|
||||
input: "text-default-500 text-small",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -15,7 +15,7 @@ export const TableLink = ({ href, label, isDisabled }: TableLinkProps) => {
|
||||
asLink={href}
|
||||
ariaLabel={label}
|
||||
variant="ghost"
|
||||
className="text-xs font-medium text-default-500 hover:text-primary disabled:opacity-30"
|
||||
className="text-default-500 hover:text-primary text-xs font-medium disabled:opacity-30"
|
||||
size="sm"
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { Textarea } from "@nextui-org/react";
|
||||
import { Textarea } from "@heroui/input";
|
||||
import React from "react";
|
||||
import { Control, FieldPath, FieldValues } from "react-hook-form";
|
||||
|
||||
|
||||
Reference in new issue
Block a user