Initial commit: Industrial HMI system with component architecture
- Implement WebView2-based HMI frontend with React + TypeScript + Vite - Add C# .NET backend with WebSocket communication layer - Separate UI components into modular structure: * RecipePanel: Recipe selection and management * IOPanel: I/O monitoring and control (32 inputs/outputs) * MotionPanel: Servo control for X/Y/Z axes * CameraPanel: Vision system feed with HUD overlay * SettingsModal: System configuration management - Create reusable UI components (CyberPanel, TechButton, PanelHeader) - Implement dual-mode communication (WebView2 native + WebSocket fallback) - Add 3D visualization with Three.js/React Three Fiber - Fix JSON parsing bug in configuration save handler - Include comprehensive .gitignore for .NET and Node.js projects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
29
frontend/components/common/CyberPanel.tsx
Normal file
29
frontend/components/common/CyberPanel.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
|
||||
interface CyberPanelProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const CyberPanel: React.FC<CyberPanelProps> = ({ children, className = "" }) => (
|
||||
<div className={`glass-holo p-1 relative group ${className}`}>
|
||||
{/* Decorative Corners */}
|
||||
<svg className="absolute top-0 left-0 w-6 h-6 text-neon-blue opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M2 22V2H22" />
|
||||
</svg>
|
||||
<svg className="absolute top-0 right-0 w-6 h-6 text-neon-blue opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M22 22V2H2" />
|
||||
</svg>
|
||||
<svg className="absolute bottom-0 left-0 w-6 h-6 text-neon-blue opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M2 2V22H22" />
|
||||
</svg>
|
||||
<svg className="absolute bottom-0 right-0 w-6 h-6 text-neon-blue opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M22 2V22H2" />
|
||||
</svg>
|
||||
|
||||
{/* Inner Content */}
|
||||
<div className="bg-slate-950/40 backdrop-blur-md h-full w-full p-4 relative z-10 clip-tech border border-white/5">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
19
frontend/components/common/PanelHeader.tsx
Normal file
19
frontend/components/common/PanelHeader.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { LucideIcon } from 'lucide-react';
|
||||
|
||||
interface PanelHeaderProps {
|
||||
title: string;
|
||||
icon: LucideIcon;
|
||||
}
|
||||
|
||||
export const PanelHeader: React.FC<PanelHeaderProps> = ({ title, icon: Icon }) => (
|
||||
<div className="flex items-center gap-3 mb-6 border-b border-white/10 pb-2">
|
||||
<div className="text-neon-blue animate-pulse">
|
||||
<Icon className="w-5 h-5" />
|
||||
</div>
|
||||
<h2 className="text-lg font-tech font-bold text-white tracking-[0.1em] uppercase text-shadow-glow-blue">
|
||||
{title}
|
||||
</h2>
|
||||
<div className="flex-1 h-px bg-gradient-to-r from-neon-blue/50 to-transparent"></div>
|
||||
</div>
|
||||
);
|
||||
39
frontend/components/common/TechButton.tsx
Normal file
39
frontend/components/common/TechButton.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
|
||||
interface TechButtonProps {
|
||||
children?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
active?: boolean;
|
||||
variant?: 'blue' | 'red' | 'amber' | 'green';
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const TechButton: React.FC<TechButtonProps> = ({
|
||||
children,
|
||||
onClick,
|
||||
active = false,
|
||||
variant = 'blue',
|
||||
className = ''
|
||||
}) => {
|
||||
const colors = {
|
||||
blue: 'from-blue-600 to-cyan-600 hover:shadow-glow-blue border-cyan-400/30',
|
||||
red: 'from-red-600 to-pink-600 hover:shadow-glow-red border-red-400/30',
|
||||
amber: 'from-amber-500 to-orange-600 hover:shadow-orange-500/50 border-orange-400/30',
|
||||
green: 'from-emerald-500 to-green-600 hover:shadow-green-500/50 border-green-400/30'
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={`
|
||||
relative px-4 py-2 font-tech font-bold tracking-wider uppercase transition-all duration-300
|
||||
clip-tech border-b-2 border-r-2
|
||||
${active ? `bg-gradient-to-r ${colors[variant]} text-white` : 'bg-slate-800/50 text-slate-400 hover:text-white hover:bg-slate-700/50 border-slate-600'}
|
||||
${className}
|
||||
`}
|
||||
>
|
||||
{active && <div className="absolute inset-0 bg-white/20 animate-pulse pointer-events-none"></div>}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user