Spaces:
Sleeping
Sleeping
| import React from 'react'; | |
| import { AlertCircle, CheckCircle, Info } from 'lucide-react'; | |
| import { cn } from '@/lib/utils'; | |
| interface ValidationMessageProps { | |
| type: 'error' | 'success' | 'info' | 'warning'; | |
| message: string; | |
| className?: string; | |
| } | |
| export const ValidationMessage: React.FC<ValidationMessageProps> = ({ | |
| type, | |
| message, | |
| className | |
| }) => { | |
| const getIcon = () => { | |
| switch (type) { | |
| case 'error': | |
| return <AlertCircle className="h-4 w-4" />; | |
| case 'success': | |
| return <CheckCircle className="h-4 w-4" />; | |
| case 'info': | |
| case 'warning': | |
| return <Info className="h-4 w-4" />; | |
| default: | |
| return null; | |
| } | |
| }; | |
| const getStyles = () => { | |
| switch (type) { | |
| case 'error': | |
| return 'text-destructive bg-destructive/10 border-destructive/20'; | |
| case 'success': | |
| return 'text-green-600 bg-green-50 border-green-200 dark:text-green-400 dark:bg-green-950 dark:border-green-800'; | |
| case 'warning': | |
| return 'text-yellow-600 bg-yellow-50 border-yellow-200 dark:text-yellow-400 dark:bg-yellow-950 dark:border-yellow-800'; | |
| case 'info': | |
| return 'text-blue-600 bg-blue-50 border-blue-200 dark:text-blue-400 dark:bg-blue-950 dark:border-blue-800'; | |
| default: | |
| return ''; | |
| } | |
| }; | |
| return ( | |
| <div className={cn( | |
| 'flex items-start gap-2 p-3 rounded-md border text-sm', | |
| getStyles(), | |
| className | |
| )}> | |
| {getIcon()} | |
| <span className="flex-1">{message}</span> | |
| </div> | |
| ); | |
| }; | |
| interface FormFieldHelpProps { | |
| children: React.ReactNode; | |
| className?: string; | |
| } | |
| export const FormFieldHelp: React.FC<FormFieldHelpProps> = ({ children, className }) => { | |
| return ( | |
| <div className={cn('text-xs text-muted-foreground mt-1', className)}> | |
| {children} | |
| </div> | |
| ); | |
| }; | |
| interface ValidationRulesProps { | |
| rules: Array<{ | |
| text: string; | |
| isValid?: boolean; | |
| }>; | |
| className?: string; | |
| } | |
| export const ValidationRules: React.FC<ValidationRulesProps> = ({ rules, className }) => { | |
| return ( | |
| <div className={cn('space-y-1 mt-2', className)}> | |
| {rules.map((rule, index) => ( | |
| <div key={index} className="flex items-center gap-2 text-xs"> | |
| {rule.isValid !== undefined && ( | |
| rule.isValid ? ( | |
| <CheckCircle className="h-3 w-3 text-green-500" /> | |
| ) : ( | |
| <AlertCircle className="h-3 w-3 text-destructive" /> | |
| ) | |
| )} | |
| <span className={cn( | |
| rule.isValid === true && 'text-green-600 dark:text-green-400', | |
| rule.isValid === false && 'text-destructive', | |
| rule.isValid === undefined && 'text-muted-foreground' | |
| )}> | |
| {rule.text} | |
| </span> | |
| </div> | |
| ))} | |
| </div> | |
| ); | |
| }; | |
| // Helper function to validate serial number format | |
| export const validateSerialNumber = (value: string) => { | |
| const rules = [ | |
| { | |
| text: 'Must not be empty', | |
| isValid: value.trim().length > 0 | |
| }, | |
| { | |
| text: 'Must be 1-50 characters long', | |
| isValid: value.length >= 1 && value.length <= 50 | |
| }, | |
| { | |
| text: 'Can only contain letters, numbers, hyphens, and underscores', | |
| isValid: /^[A-Za-z0-9\-_]*$/.test(value) | |
| } | |
| ]; | |
| return { | |
| isValid: rules.every(rule => rule.isValid), | |
| rules | |
| }; | |
| }; | |
| // Helper function to validate screen resolution format | |
| export const validateScreenResolution = (value: string) => { | |
| const rules = [ | |
| { | |
| text: 'Must not be empty', | |
| isValid: value.trim().length > 0 | |
| }, | |
| { | |
| text: 'Must be in format "1920x1080" or select from dropdown', | |
| isValid: /^\d+x\d+$/.test(value.trim()) || value === 'custom' | |
| } | |
| ]; | |
| return { | |
| isValid: rules.every(rule => rule.isValid), | |
| rules | |
| }; | |
| }; | |
| export default { | |
| ValidationMessage, | |
| FormFieldHelp, | |
| ValidationRules, | |
| validateSerialNumber, | |
| validateScreenResolution | |
| }; |