mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
feat(ui): add RadioCard and AWS method selector components
Add reusable RadioCard component for selectable card options. Add AwsMethodSelector that presents single-account vs Organizations bulk connect, with Organizations gated behind NEXT_PUBLIC_IS_CLOUD_ENV.
This commit is contained in:
@@ -5,4 +5,5 @@ export * from "./forms/delete-form";
|
||||
export * from "./link-to-scans";
|
||||
export * from "./muted-findings-config-button";
|
||||
export * from "./provider-info";
|
||||
export * from "./radio-card";
|
||||
export * from "./radio-group-provider";
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import { ArrowRightCircle, Ban, Box } from "lucide-react";
|
||||
|
||||
import { RadioCard } from "@/components/providers/radio-card";
|
||||
|
||||
interface AwsMethodSelectorProps {
|
||||
onSelectSingle: () => void;
|
||||
onSelectOrganizations: () => void;
|
||||
}
|
||||
|
||||
export function AwsMethodSelector({
|
||||
onSelectSingle,
|
||||
onSelectOrganizations,
|
||||
}: AwsMethodSelectorProps) {
|
||||
const isCloudEnv = process.env.NEXT_PUBLIC_IS_CLOUD_ENV === "true";
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<p className="text-muted-foreground text-sm">
|
||||
Select a method to add your accounts to Prowler.
|
||||
</p>
|
||||
|
||||
<RadioCard
|
||||
icon={Box}
|
||||
title="Add A Single AWS Cloud Account"
|
||||
onClick={onSelectSingle}
|
||||
/>
|
||||
|
||||
<RadioCard
|
||||
icon={Ban}
|
||||
title="Add Multiple Accounts With AWS Organizations"
|
||||
onClick={onSelectOrganizations}
|
||||
disabled={!isCloudEnv}
|
||||
>
|
||||
{!isCloudEnv && <CtaBadge />}
|
||||
</RadioCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function CtaBadge() {
|
||||
return (
|
||||
<a
|
||||
href="https://prowler.com/pricing"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex h-[52px] shrink-0 items-center justify-center rounded-lg px-4 py-3 transition-opacity hover:opacity-90"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"linear-gradient(112deg, rgb(46, 229, 155) 3.5%, rgb(98, 223, 240) 98.8%)",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<ArrowRightCircle className="text-primary-foreground size-5" />
|
||||
<span className="text-primary-foreground text-sm leading-6 font-bold">
|
||||
Get Prowler Cloud
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface RadioCardProps {
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
title: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
/** Optional trailing content (e.g. a CTA badge). */
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function RadioCard({
|
||||
icon: Icon,
|
||||
title,
|
||||
onClick,
|
||||
disabled = false,
|
||||
children,
|
||||
}: RadioCardProps) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
"flex min-h-[72px] w-full items-center gap-4 rounded-lg border px-3 py-2.5 text-left transition-colors",
|
||||
disabled
|
||||
? "cursor-not-allowed border-border-neutral-primary bg-bg-neutral-tertiary"
|
||||
: "hover:border-primary cursor-pointer border-border-neutral-primary bg-bg-neutral-tertiary",
|
||||
)}
|
||||
>
|
||||
<div className="size-[18px] shrink-0 rounded-full border border-border-neutral-primary bg-bg-input-primary shadow-xs" />
|
||||
|
||||
<div className="flex min-w-0 flex-1 items-center gap-1.5">
|
||||
<Icon
|
||||
className={cn(
|
||||
"size-[18px] shrink-0",
|
||||
disabled ? "text-text-neutral-tertiary" : "text-muted-foreground",
|
||||
)}
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
"truncate text-sm leading-6",
|
||||
disabled ? "text-text-neutral-tertiary" : "text-foreground",
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user