mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
Compare commits
5 Commits
489454b5c6
...
PRWLR-7512
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98047e690d | ||
|
|
fa11e98a55 | ||
|
|
ff691f1d37 | ||
|
|
819c9306ee | ||
|
|
bfc72170c5 |
@@ -7,6 +7,7 @@ All notable changes to the **Prowler UI** are documented in this file.
|
||||
### 🚀 Added
|
||||
|
||||
- SAML login integration [(#8203)](https://github.com/prowler-cloud/prowler/pull/8203)
|
||||
- Introduced new `CustomLink` component for handling all navigation and link-related behavior [(#8195)] (https://github.com/prowler-cloud/prowler/pull/8195)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { InfoIcon } from "../icons/Icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const NoScansAvailable = () => {
|
||||
return (
|
||||
@@ -23,8 +24,8 @@ export const NoScansAvailable = () => {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<CustomButton
|
||||
asLink="/scans"
|
||||
<CustomLink
|
||||
href="/scans"
|
||||
className="flex-shrink-0"
|
||||
ariaLabel="Go to Scans page"
|
||||
variant="solid"
|
||||
@@ -32,7 +33,7 @@ export const NoScansAvailable = () => {
|
||||
size="sm"
|
||||
>
|
||||
Go to Scans
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Tooltip } from "@nextui-org/react";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom/custom-button";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface DeltaIndicatorProps {
|
||||
@@ -18,16 +18,16 @@ export const DeltaIndicator = ({ delta }: DeltaIndicatorProps) => {
|
||||
? "New finding."
|
||||
: "Status changed since the previous scan."}
|
||||
</span>
|
||||
<CustomButton
|
||||
<CustomLink
|
||||
ariaLabel="Learn more about findings"
|
||||
color="transparent"
|
||||
size="sm"
|
||||
className="h-auto min-w-0 p-0 text-primary"
|
||||
asLink="https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/prowler-app/#step-8-analyze-the-findings"
|
||||
href="https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/prowler-app/#step-8-analyze-the-findings"
|
||||
target="_blank"
|
||||
>
|
||||
Learn more
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
import { Card, CardBody, Divider, Snippet } from "@nextui-org/react";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { AddIcon } from "../icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
import { DateWithTime } from "../ui/entities";
|
||||
|
||||
interface InvitationDetailsProps {
|
||||
@@ -108,8 +109,8 @@ export const InvitationDetails = ({ attributes }: InvitationDetailsProps) => {
|
||||
</CardBody>
|
||||
</Card>
|
||||
<div className="flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/invitations/"
|
||||
<CustomLink
|
||||
href={"/invitations/"}
|
||||
ariaLabel="Send Invitation"
|
||||
variant="solid"
|
||||
color="action"
|
||||
@@ -117,7 +118,7 @@ export const InvitationDetails = ({ attributes }: InvitationDetailsProps) => {
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Back to Invitations
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { AddIcon } from "../icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const SendInvitationButton = () => {
|
||||
return (
|
||||
<div className="flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/invitations/new"
|
||||
<CustomLink
|
||||
href={"/invitations/new"}
|
||||
ariaLabel="Send Invitation"
|
||||
variant="solid"
|
||||
color="action"
|
||||
@@ -15,7 +16,7 @@ export const SendInvitationButton = () => {
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Send Invitation
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
|
||||
import { CustomButton } from "../ui/custom";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
export const ManageGroupsButton = () => {
|
||||
return (
|
||||
<CustomButton
|
||||
asLink="/manage-groups"
|
||||
<CustomLink
|
||||
href={"/manage-groups"}
|
||||
ariaLabel="Manage Groups"
|
||||
variant="dashed"
|
||||
color="warning"
|
||||
color="secondary"
|
||||
size="md"
|
||||
startContent={<SettingsIcon size={20} />}
|
||||
>
|
||||
Manage Groups
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
export const LinkToFindings = () => {
|
||||
return (
|
||||
<div className="mt-4 flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/findings?sort=severity,-inserted_at&filter[status__in]=FAIL&filter[delta__in]=new"
|
||||
<CustomLink
|
||||
href="/findings?sort=severity,-inserted_at&filter[status__in]=FAIL&filter[delta__in]=new"
|
||||
ariaLabel="Go to Findings page"
|
||||
variant="solid"
|
||||
color="action"
|
||||
size="sm"
|
||||
>
|
||||
Check out on Findings
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
KS8ProviderBadge,
|
||||
M365ProviderBadge,
|
||||
} from "@/components/icons/providers-badge";
|
||||
import { CustomButton } from "@/components/ui/custom/custom-button";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
import { ProviderOverviewProps } from "@/types";
|
||||
|
||||
export const ProvidersOverview = ({
|
||||
@@ -178,8 +178,8 @@ export const ProvidersOverview = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/providers"
|
||||
<CustomLink
|
||||
href="/providers"
|
||||
ariaLabel="Go to Providers page"
|
||||
variant="solid"
|
||||
color="action"
|
||||
@@ -187,7 +187,7 @@ export const ProvidersOverview = ({
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Add Provider
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
"use client";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { AddIcon } from "../icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const AddProviderButton = () => {
|
||||
return (
|
||||
<CustomButton
|
||||
asLink="/providers/connect-account"
|
||||
<CustomLink
|
||||
href="/providers/connect-account"
|
||||
ariaLabel="Add Cloud Provider"
|
||||
variant="solid"
|
||||
color="action"
|
||||
size="md"
|
||||
color="action"
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Add Cloud Provider
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
interface LinkToScansProps {
|
||||
providerUid?: string;
|
||||
@@ -8,14 +8,14 @@ interface LinkToScansProps {
|
||||
|
||||
export const LinkToScans = ({ providerUid }: LinkToScansProps) => {
|
||||
return (
|
||||
<CustomButton
|
||||
asLink={`/scans?filter[provider_uid]=${providerUid}`}
|
||||
<CustomLink
|
||||
href={`/scans?filter[provider_uid]=${providerUid}`}
|
||||
ariaLabel="Go to Scans page"
|
||||
variant="solid"
|
||||
color="action"
|
||||
size="sm"
|
||||
>
|
||||
View Scan Jobs
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Snippet } from "@nextui-org/react";
|
||||
import { useSession } from "next-auth/react";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
import { getAWSCredentialsTemplateLinks } from "@/lib";
|
||||
|
||||
export const CredentialsRoleHelper = () => {
|
||||
@@ -16,15 +16,15 @@ export const CredentialsRoleHelper = () => {
|
||||
A <strong>new read-only IAM role</strong> must be manually created.
|
||||
</p>
|
||||
|
||||
<CustomButton
|
||||
<CustomLink
|
||||
ariaLabel="Use the following AWS CloudFormation Quick Link to deploy the IAM Role"
|
||||
color="transparent"
|
||||
className="h-auto w-fit min-w-0 p-0 text-blue-500"
|
||||
asLink={`${getAWSCredentialsTemplateLinks().cloudformationQuickLink}${session?.tenantId}`}
|
||||
variant="textLink"
|
||||
href={`${getAWSCredentialsTemplateLinks().cloudformationQuickLink}${session?.tenantId}`}
|
||||
target="_blank"
|
||||
>
|
||||
Use the following AWS CloudFormation Quick Link to deploy the IAM Role
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="h-px flex-1 bg-gray-200 dark:bg-gray-700" />
|
||||
@@ -38,24 +38,24 @@ export const CredentialsRoleHelper = () => {
|
||||
</p>
|
||||
|
||||
<div className="flex w-fit flex-col gap-2">
|
||||
<CustomButton
|
||||
<CustomLink
|
||||
ariaLabel="CloudFormation Template"
|
||||
color="transparent"
|
||||
className="h-auto w-fit min-w-0 p-0 text-blue-500"
|
||||
asLink={getAWSCredentialsTemplateLinks().cloudformation}
|
||||
variant="textLink"
|
||||
href={getAWSCredentialsTemplateLinks().cloudformation}
|
||||
target="_blank"
|
||||
>
|
||||
CloudFormation Template
|
||||
</CustomButton>
|
||||
<CustomButton
|
||||
</CustomLink>
|
||||
<CustomLink
|
||||
ariaLabel="Terraform Code"
|
||||
color="transparent"
|
||||
className="h-auto w-fit min-w-0 p-0 text-blue-500"
|
||||
asLink={getAWSCredentialsTemplateLinks().terraform}
|
||||
variant="textLink"
|
||||
href={getAWSCredentialsTemplateLinks().terraform}
|
||||
target="_blank"
|
||||
>
|
||||
Terraform Code
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
|
||||
<p className="text-xs font-bold text-gray-600 dark:text-gray-400">
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { AddIcon } from "../icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const AddRoleButton = () => {
|
||||
return (
|
||||
<div className="flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/roles/new"
|
||||
<CustomLink
|
||||
href="/roles/new"
|
||||
ariaLabel="Add Role"
|
||||
variant="solid"
|
||||
color="action"
|
||||
@@ -15,7 +16,7 @@ export const AddRoleButton = () => {
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Add Role
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
interface LinkToFindingsProps {
|
||||
scanId?: string;
|
||||
@@ -12,15 +12,15 @@ export const LinkToFindingsFromScan = ({
|
||||
isDisabled,
|
||||
}: LinkToFindingsProps) => {
|
||||
return (
|
||||
<CustomButton
|
||||
asLink={`/findings?filter[scan__in]=${scanId}&filter[status__in]=FAIL`}
|
||||
<CustomLink
|
||||
href={`/findings?filter[scan__in]=${scanId}&filter[status__in]=FAIL`}
|
||||
ariaLabel="Go to Findings page"
|
||||
color="muted"
|
||||
variant="ghost"
|
||||
className="text-xs font-medium text-default-500 hover:text-primary disabled:opacity-30"
|
||||
size="sm"
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
See Findings
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
import { Card, CardBody } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { InfoIcon } from "../icons/Icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const NoProvidersAdded = () => {
|
||||
return (
|
||||
@@ -25,16 +26,16 @@ export const NoProvidersAdded = () => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<CustomButton
|
||||
asLink="/providers/connect-account"
|
||||
<CustomLink
|
||||
href="/providers/connect-account"
|
||||
ariaLabel="Go to Add Cloud Provider page"
|
||||
className="w-full max-w-xs justify-center"
|
||||
variant="solid"
|
||||
color="action"
|
||||
size="lg"
|
||||
size="md"
|
||||
>
|
||||
Get Started
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { InfoIcon } from "../icons/Icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const NoProvidersConnected = () => {
|
||||
return (
|
||||
@@ -26,8 +27,8 @@ export const NoProvidersConnected = () => {
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full md:w-auto md:flex-shrink-0">
|
||||
<CustomButton
|
||||
asLink="/providers"
|
||||
<CustomLink
|
||||
href="/providers"
|
||||
className="w-full justify-center md:w-fit"
|
||||
ariaLabel="Go to Cloud providers page"
|
||||
variant="solid"
|
||||
@@ -35,7 +36,7 @@ export const NoProvidersConnected = () => {
|
||||
size="md"
|
||||
>
|
||||
Review Cloud Providers
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Button, CircularProgress } from "@nextui-org/react";
|
||||
import type { PressEvent } from "@react-types/shared";
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
import { NextUIColors, NextUIVariants } from "@/types";
|
||||
@@ -53,7 +52,6 @@ interface CustomButtonProps {
|
||||
isLoading?: boolean;
|
||||
isIconOnly?: boolean;
|
||||
ref?: React.RefObject<HTMLButtonElement>;
|
||||
asLink?: string;
|
||||
}
|
||||
|
||||
export const CustomButton = React.forwardRef<
|
||||
@@ -78,14 +76,11 @@ export const CustomButton = React.forwardRef<
|
||||
isDisabled = false,
|
||||
isLoading = false,
|
||||
isIconOnly,
|
||||
asLink,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => (
|
||||
<Button
|
||||
as={asLink ? Link : undefined}
|
||||
href={asLink}
|
||||
target={target}
|
||||
type={type}
|
||||
aria-label={ariaLabel}
|
||||
|
||||
140
ui/components/ui/custom/custom-link.tsx
Normal file
140
ui/components/ui/custom/custom-link.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
import { cn } from "@/lib";
|
||||
|
||||
interface CustomLinkProps
|
||||
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
href: string;
|
||||
target?: "_self" | "_blank";
|
||||
rel?: string;
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
variant?:
|
||||
| "default"
|
||||
| "dashed"
|
||||
| "ghost"
|
||||
| "block"
|
||||
| "solid"
|
||||
| "unstyled"
|
||||
| "iconButton"
|
||||
| "textLink";
|
||||
color?:
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "action"
|
||||
| "transparent"
|
||||
| "danger"
|
||||
| "success"
|
||||
| "muted";
|
||||
size?: "md" | "sm" | "lg";
|
||||
startContent?: React.ReactNode;
|
||||
endContent?: React.ReactNode;
|
||||
isIconOnly?: boolean;
|
||||
ariaLabel?: string;
|
||||
isDisabled?: boolean;
|
||||
}
|
||||
|
||||
const linkClasses = {
|
||||
base: "inline-flex items-center gap-1 text-sm font-medium transition-colors duration-200",
|
||||
iconOnly: "p-2 rounded-full justify-center",
|
||||
disabled: "opacity-30 pointer-events-none cursor-not-allowed",
|
||||
};
|
||||
|
||||
const variantClasses = {
|
||||
default: "",
|
||||
dashed:
|
||||
"border border-default border-dashed bg-transparent justify-center whitespace-nowrap shadow-sm hover:border-solid hover:bg-default-100 active:bg-default-200 active:border-solid",
|
||||
iconButton:
|
||||
"whitespace-nowrap rounded-[14px] border-2 border-gray-200 bg-prowler-grey-medium p-3 bg-transparent",
|
||||
ghost:
|
||||
"whitespace-nowrap border border-prowler-theme-green text-default-500 hover:bg-prowler-theme-green hover:!text-black disabled:opacity-30",
|
||||
solid: "whitespace-nowrap min-w-20",
|
||||
textLink: "h-auto w-fit min-w-0 p-0 text-blue-500",
|
||||
block: "block w-full text-left",
|
||||
unstyled: "",
|
||||
};
|
||||
|
||||
const colorClasses = {
|
||||
primary: "text-prowler-theme-green",
|
||||
secondary: "text-default-800 dark:text-white",
|
||||
action:
|
||||
"bg-prowler-theme-green font-bold text-prowler-theme-midnight hover:opacity-80 transition-opacity duration-100",
|
||||
transparent: "border-0 border-transparent bg-transparent",
|
||||
danger: "text-red-600 dark:text-red-400",
|
||||
success: "text-green-600 dark:text-green-400",
|
||||
muted: "text-gray-500 dark:text-gray-400",
|
||||
};
|
||||
|
||||
const sizeClasses = {
|
||||
sm: "text-xs px-4 h-8 rounded-lg",
|
||||
md: "text-sm px-4 py-2 h-10 rounded-lg",
|
||||
lg: "text-lg px-5 py-3 h-12 rounded-xl",
|
||||
};
|
||||
|
||||
export const CustomLink = React.forwardRef<HTMLAnchorElement, CustomLinkProps>(
|
||||
(
|
||||
{
|
||||
href,
|
||||
target = "_self",
|
||||
rel,
|
||||
className,
|
||||
children,
|
||||
variant = "default",
|
||||
color = "primary",
|
||||
size = "md",
|
||||
startContent,
|
||||
endContent,
|
||||
isIconOnly = false,
|
||||
ariaLabel,
|
||||
isDisabled = false,
|
||||
...rest
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const isExternal = target === "_blank";
|
||||
const computedRel = isExternal ? "noopener noreferrer" : rel;
|
||||
|
||||
const content = (
|
||||
<>
|
||||
{startContent && <span>{startContent}</span>}
|
||||
{!isIconOnly && children}
|
||||
{endContent && <span>{endContent}</span>}
|
||||
</>
|
||||
);
|
||||
|
||||
const combinedClasses = cn(
|
||||
linkClasses.base,
|
||||
colorClasses[color],
|
||||
sizeClasses[size],
|
||||
variantClasses[variant],
|
||||
isIconOnly && linkClasses.iconOnly,
|
||||
isDisabled && linkClasses.disabled,
|
||||
className,
|
||||
);
|
||||
|
||||
return isDisabled ? (
|
||||
<span
|
||||
className={combinedClasses}
|
||||
aria-disabled="true"
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
{content}
|
||||
</span>
|
||||
) : (
|
||||
<Link
|
||||
href={href}
|
||||
target={target}
|
||||
rel={computedRel}
|
||||
ref={ref}
|
||||
aria-label={ariaLabel}
|
||||
className={combinedClasses}
|
||||
{...rest}
|
||||
>
|
||||
{content}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
CustomLink.displayName = "CustomLink";
|
||||
@@ -4,6 +4,7 @@ export * from "./custom-button";
|
||||
export * from "./custom-dropdown-filter";
|
||||
export * from "./custom-dropdown-selection";
|
||||
export * from "./custom-input";
|
||||
export * from "./custom-link";
|
||||
export * from "./custom-loader";
|
||||
export * from "./custom-radio";
|
||||
export * from "./custom-server-input";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Icon } from "@iconify/react";
|
||||
import { Divider } from "@nextui-org/react";
|
||||
import React from "react";
|
||||
|
||||
import { CustomButton } from "@/components/ui/custom/custom-button";
|
||||
import { CustomLink } from "@/components/ui/custom/custom-link";
|
||||
|
||||
interface NavigationHeaderProps {
|
||||
title: string;
|
||||
@@ -18,16 +18,14 @@ export const NavigationHeader: React.FC<NavigationHeaderProps> = ({
|
||||
return (
|
||||
<>
|
||||
<header className="flex items-center gap-3 border-b border-gray-200 px-6 py-4 dark:border-gray-800">
|
||||
<CustomButton
|
||||
asLink={href || ""}
|
||||
className="border-gray-200 bg-transparent p-0"
|
||||
<CustomLink
|
||||
href={href || ""}
|
||||
variant="iconButton"
|
||||
ariaLabel="Navigation button"
|
||||
variant="bordered"
|
||||
isIconOnly
|
||||
radius="lg"
|
||||
color="muted"
|
||||
>
|
||||
<Icon icon={icon} className="text-gray-600 dark:text-gray-400" />
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
<Divider orientation="vertical" className="h-6" />
|
||||
<h1 className="text-xl font-light text-default-700">{title}</h1>
|
||||
</header>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { usePathname } from "next/navigation";
|
||||
|
||||
import { logOut } from "@/actions/auth";
|
||||
import { AddIcon, InfoIcon } from "@/components/icons";
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
import { CollapseMenuButton } from "@/components/ui/sidebar/collapse-menu-button";
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -18,7 +19,6 @@ import { getMenuList } from "@/lib/menu-list";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { Button } from "../button/button";
|
||||
import { CustomButton } from "../custom/custom-button";
|
||||
import { ScrollArea } from "../scroll-area/scroll-area";
|
||||
|
||||
export const Menu = ({ isOpen }: { isOpen: boolean }) => {
|
||||
@@ -28,17 +28,17 @@ export const Menu = ({ isOpen }: { isOpen: boolean }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="px-2">
|
||||
<CustomButton
|
||||
asLink="/scans"
|
||||
className={cn(isOpen ? "w-full" : "w-fit")}
|
||||
ariaLabel="Launch Scan"
|
||||
<CustomLink
|
||||
href="/scans"
|
||||
className={cn(isOpen ? "w-full" : "w-fit", "justify-center")}
|
||||
variant="solid"
|
||||
ariaLabel="Launch Scan"
|
||||
color="action"
|
||||
size="md"
|
||||
endContent={isOpen ? <AddIcon size={20} /> : null}
|
||||
>
|
||||
{isOpen ? "Launch Scan" : <AddIcon size={20} />}
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
<ScrollArea className="[&>div>div[style]]:!block">
|
||||
<nav className="mt-2 h-full w-full lg:mt-6">
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { CustomLink } from "@/components/ui/custom";
|
||||
|
||||
import { AddIcon } from "../icons";
|
||||
import { CustomButton } from "../ui/custom";
|
||||
|
||||
export const AddUserButton = () => {
|
||||
return (
|
||||
<div className="flex w-full items-center justify-end">
|
||||
<CustomButton
|
||||
asLink="/invitations/new"
|
||||
<CustomLink
|
||||
href="/invitations/new"
|
||||
ariaLabel="Invite User"
|
||||
variant="solid"
|
||||
color="action"
|
||||
@@ -15,7 +16,7 @@ export const AddUserButton = () => {
|
||||
endContent={<AddIcon size={20} />}
|
||||
>
|
||||
Invite User
|
||||
</CustomButton>
|
||||
</CustomLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user