feat: Major update with validators, skills, dashboard, and docs reorganization
- Add validation framework (config, model, results, study validators) - Add Claude Code skills (create-study, run-optimization, generate-report, troubleshoot, analyze-model) - Add Atomizer Dashboard (React frontend + FastAPI backend) - Reorganize docs into structured directories (00-09) - Add neural surrogate modules and training infrastructure - Add multi-objective optimization support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
51
atomizer-dashboard/frontend/src/components/common/Button.tsx
Normal file
51
atomizer-dashboard/frontend/src/components/common/Button.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
isLoading?: boolean;
|
||||
icon?: ReactNode;
|
||||
}
|
||||
|
||||
export const Button = ({
|
||||
children,
|
||||
className,
|
||||
variant = 'primary',
|
||||
size = 'md',
|
||||
isLoading = false,
|
||||
icon,
|
||||
disabled,
|
||||
...props
|
||||
}: ButtonProps) => {
|
||||
const variants = {
|
||||
primary: 'bg-primary-600 hover:bg-primary-700 text-white shadow-sm',
|
||||
secondary: 'bg-dark-700 hover:bg-dark-600 text-dark-100 border border-dark-600',
|
||||
danger: 'bg-red-600 hover:bg-red-700 text-white',
|
||||
ghost: 'hover:bg-dark-700 text-dark-300 hover:text-white',
|
||||
};
|
||||
|
||||
const sizes = {
|
||||
sm: 'px-3 py-1.5 text-sm',
|
||||
md: 'px-4 py-2',
|
||||
lg: 'px-6 py-3 text-lg',
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={clsx(
|
||||
'inline-flex items-center justify-center rounded-lg font-medium transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
variants[variant],
|
||||
sizes[size],
|
||||
className
|
||||
)}
|
||||
disabled={disabled || isLoading}
|
||||
{...props}
|
||||
>
|
||||
{isLoading && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
||||
{!isLoading && icon && <span className="mr-2">{icon}</span>}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
21
atomizer-dashboard/frontend/src/components/common/Card.tsx
Normal file
21
atomizer-dashboard/frontend/src/components/common/Card.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ReactNode } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
interface CardProps {
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const Card = ({ title, children, className }: CardProps) => {
|
||||
return (
|
||||
<div className={clsx('bg-dark-800 rounded-xl border border-dark-600 shadow-sm overflow-hidden', className)}>
|
||||
{title && (
|
||||
<div className="px-6 py-4 border-b border-dark-600">
|
||||
<h3 className="text-lg font-semibold text-white">{title}</h3>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-6">{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
39
atomizer-dashboard/frontend/src/components/common/Input.tsx
Normal file
39
atomizer-dashboard/frontend/src/components/common/Input.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { InputHTMLAttributes, forwardRef } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
error?: string;
|
||||
helperText?: string;
|
||||
}
|
||||
|
||||
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
({ className, label, error, helperText, ...props }, ref) => {
|
||||
return (
|
||||
<div className="w-full">
|
||||
{label && (
|
||||
<label className="block text-sm font-medium text-dark-200 mb-1.5">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<input
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'w-full bg-dark-800 border rounded-lg px-3 py-2 text-dark-50 placeholder-dark-400 focus:outline-none focus:ring-2 focus:ring-primary-500/50 transition-all duration-200',
|
||||
error
|
||||
? 'border-red-500 focus:border-red-500'
|
||||
: 'border-dark-600 focus:border-primary-500',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
{error && <p className="mt-1 text-sm text-red-400">{error}</p>}
|
||||
{helperText && !error && (
|
||||
<p className="mt-1 text-sm text-dark-400">{helperText}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Input.displayName = 'Input';
|
||||
Reference in New Issue
Block a user