Spaces:
Sleeping
Sleeping
| 'use client' | |
| import { useState } from 'react' | |
| import { TeamContext } from '@/lib/types' | |
| interface ContextFormProps { | |
| onSubmit: (context: TeamContext) => void | |
| onBack: () => void | |
| } | |
| const defaultContext: TeamContext = { | |
| architecture: 'monolith', | |
| releaseStrategy: 'scheduled', | |
| hasComplianceConstraints: false, | |
| } | |
| export default function ContextForm({ onSubmit, onBack }: ContextFormProps) { | |
| const [context, setContext] = useState<TeamContext>(defaultContext) | |
| function handleSubmit(e: React.FormEvent) { | |
| e.preventDefault() | |
| onSubmit(context) | |
| } | |
| function setField<K extends keyof TeamContext>(key: K, value: TeamContext[K]) { | |
| setContext((prev) => ({ ...prev, [key]: value })) | |
| } | |
| return ( | |
| <form onSubmit={handleSubmit} className="space-y-6"> | |
| <div> | |
| <fieldset> | |
| <legend className="block text-sm font-medium text-gray-700 mb-2">Architecture</legend> | |
| <div className="space-y-2"> | |
| {( | |
| [ | |
| { value: 'monolith', label: 'Monolith' }, | |
| { value: 'microservices', label: 'Microservices' }, | |
| { value: 'hybrid', label: 'Hybrid' }, | |
| ] as const | |
| ).map(({ value, label }) => ( | |
| <label key={value} className="flex items-center gap-3 cursor-pointer"> | |
| <input | |
| type="radio" | |
| name="architecture" | |
| value={value} | |
| checked={context.architecture === value} | |
| onChange={() => setField('architecture', value)} | |
| className="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600" | |
| /> | |
| <span className="text-sm text-gray-700">{label}</span> | |
| </label> | |
| ))} | |
| </div> | |
| </fieldset> | |
| </div> | |
| <div> | |
| <fieldset> | |
| <legend className="block text-sm font-medium text-gray-700 mb-2">Release Strategy</legend> | |
| <div className="space-y-2"> | |
| {( | |
| [ | |
| { value: 'continuous', label: 'Continuous delivery' }, | |
| { value: 'scheduled', label: 'Scheduled releases' }, | |
| { value: 'mixed', label: 'Mixed' }, | |
| ] as const | |
| ).map(({ value, label }) => ( | |
| <label key={value} className="flex items-center gap-3 cursor-pointer"> | |
| <input | |
| type="radio" | |
| name="releaseStrategy" | |
| value={value} | |
| checked={context.releaseStrategy === value} | |
| onChange={() => setField('releaseStrategy', value)} | |
| className="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600" | |
| /> | |
| <span className="text-sm text-gray-700">{label}</span> | |
| </label> | |
| ))} | |
| </div> | |
| </fieldset> | |
| </div> | |
| <div> | |
| <label className="flex items-center gap-3 cursor-pointer"> | |
| <input | |
| type="checkbox" | |
| checked={context.hasComplianceConstraints} | |
| onChange={(e) => setField('hasComplianceConstraints', e.target.checked)} | |
| className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600" | |
| /> | |
| <span className="text-sm font-medium text-gray-700"> | |
| Team has compliance constraints (e.g. SOC2, HIPAA, PCI) | |
| </span> | |
| </label> | |
| </div> | |
| <div className="flex gap-3 pt-2"> | |
| <button | |
| type="button" | |
| onClick={onBack} | |
| className="flex-1 rounded-md border border-gray-300 bg-white px-4 py-2.5 text-sm font-semibold text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" | |
| > | |
| Back | |
| </button> | |
| <button | |
| type="submit" | |
| className="flex-1 rounded-md bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" | |
| > | |
| Generate Report | |
| </button> | |
| </div> | |
| </form> | |
| ) | |
| } | |