OPC # 0001: Extract OPC into standalone repo
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { useEffect } from 'react';
|
||||
import type { ProvisioningRequest, TenantEnvironment, TenantTier } from '../../types/provisioning';
|
||||
|
||||
interface Props {
|
||||
signalParent: (state: { isValid: boolean }) => void;
|
||||
data: ProvisioningRequest;
|
||||
onChange: (updated: Partial<ProvisioningRequest>) => void;
|
||||
}
|
||||
|
||||
const ENVIRONMENTS: { value: TenantEnvironment; label: string; description: string }[] = [
|
||||
{ value: 'fdev', label: 'Dev (fdev)', description: 'Feature development - fast provisioning, no production data.' },
|
||||
{ value: 'uat', label: 'UAT', description: 'User acceptance testing - mirrors production configuration.' },
|
||||
{ value: 'prod', label: 'Production', description: 'Live production environment. Full isolation enforced.' },
|
||||
];
|
||||
|
||||
const TIERS: { value: TenantTier; label: string; description: string; badge: string }[] = [
|
||||
{
|
||||
value: 'Shared',
|
||||
label: 'Shared',
|
||||
badge: 'Standard',
|
||||
description: 'Shared Keycloak, Vault, Postgres and MinIO. Isolated by realm, namespace and bucket.',
|
||||
},
|
||||
{
|
||||
value: 'Isolated',
|
||||
label: 'Isolated',
|
||||
badge: 'Professional',
|
||||
description: 'Shared Keycloak and Vault, but a dedicated Postgres container and MinIO bucket per tenant.',
|
||||
},
|
||||
{
|
||||
value: 'Dedicated',
|
||||
label: 'Dedicated',
|
||||
badge: 'Enterprise',
|
||||
description: 'Fully dedicated Keycloak, Vault, Postgres and MinIO containers for complete hard isolation.',
|
||||
},
|
||||
];
|
||||
|
||||
export default function DeploymentConfigStep({ signalParent, data, onChange }: Props) {
|
||||
useEffect(() => {
|
||||
signalParent({ isValid: !!data.tier && !!data.environment });
|
||||
}, [data.tier, data.environment, signalParent]);
|
||||
|
||||
return (
|
||||
<div className="wizard-step">
|
||||
<p className="step-description">Choose the deployment environment and infrastructure isolation tier.</p>
|
||||
|
||||
<h4 style={{ marginBottom: '0.5rem' }}>Environment</h4>
|
||||
<div className="tier-cards" style={{ marginBottom: '1.5rem' }}>
|
||||
{ENVIRONMENTS.map((env) => (
|
||||
<button
|
||||
key={env.value}
|
||||
type="button"
|
||||
className={`tier-card${data.environment === env.value ? ' selected' : ''}`}
|
||||
onClick={() => onChange({ environment: env.value })}
|
||||
>
|
||||
<div className="tier-card-header">
|
||||
<span className="tier-card-label">{env.label}</span>
|
||||
</div>
|
||||
<p className="tier-card-description">{env.description}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h4 style={{ marginBottom: '0.5rem' }}>Isolation Tier</h4>
|
||||
<div className="tier-cards">
|
||||
{TIERS.map((tier) => (
|
||||
<button
|
||||
key={tier.value}
|
||||
type="button"
|
||||
className={`tier-card${data.tier === tier.value ? ' selected' : ''}`}
|
||||
onClick={() => onChange({ tier: tier.value })}
|
||||
>
|
||||
<div className="tier-card-header">
|
||||
<span className="tier-card-label">{tier.label}</span>
|
||||
<span className={`tier-card-badge tier-badge-${tier.value.toLowerCase()}`}>{tier.badge}</span>
|
||||
</div>
|
||||
<p className="tier-card-description">{tier.description}</p>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user