UNPKG

je_nfc_sdk

Version:

A comprehensive React Native SDK for NFC-based device control and communication

205 lines (204 loc) 9.84 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator, } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; export const NfcOperationCard = ({ operationType, config, operation, onPress, disabled = false, translate = (key) => key, theme = 'light' }) => { const isSolenoidOperation = operationType.startsWith('solenoid_'); const isTimeSetOperation = operationType === 'time_set'; const isTimeOperation = operationType.startsWith('time_'); const isWaterFlowOperation = operationType.startsWith('flowrate_'); const isPressureOperation = operationType.startsWith('pressure_'); const getStatusColor = (state) => { switch (state) { case 'IDLE': return '#6c757d'; // Progress steps: 4 for write, 3 for read const isWriteCard = isSolenoidOperation || isTimeSetOperation; case 'PROCESSING': return '#e67e22'; case 'ERROR': return '#c82333'; default: return '#6c757d'; } }; const getButtonText = () => { if (operation.resetRequested) return translate('🔄 Reset Operation'); switch (operation.state) { case 'WRITE_PENDING': return translate('📝 Writing...'); case 'READ_PENDING': return translate('📖 Reading...'); case 'PROCESSING': return translate('🔄 Processing...'); case 'IDLE': return `${config.icon} Start ${config.displayName}`; case 'READ_READY': return `📖 Read ${config.displayName}`; case 'READ_READY_READ': return `📖 Update ${config.displayName}`; case 'READ_READY_WRITE': return `📖 Get ${config.displayName}`; case 'ERROR': return `❌ Retry ${config.displayName}`; default: return `${config.icon} ${config.displayName}`; } }; // Card wrapper with gradients for different operation types const CardWrapper = ({ children }) => { if (isSolenoidOperation) { const colors = ['rgba(108, 117, 125, 0.4)', 'rgba(108, 117, 125, 0.1)', 'rgba(0, 0, 0, 0.05)']; return (_jsx(LinearGradient, Object.assign({ colors: colors, start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: [styles.card, disabled && styles.cardInactive], pointerEvents: "auto" }, { children: children }))); } else if (isTimeOperation) { return (_jsx(LinearGradient, Object.assign({ colors: ['rgba(245, 245, 220, 0.4)', 'rgba(245, 245, 220, 0.1)', 'rgba(0, 0, 0, 0.05)'], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: styles.card, pointerEvents: "auto" }, { children: children }))); } else if (isWaterFlowOperation) { return (_jsx(LinearGradient, Object.assign({ colors: ['rgba(64, 164, 223, 0.6)', 'rgba(100, 200, 255, 0.3)', 'rgba(0, 100, 180, 0.2)'], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: styles.card, pointerEvents: "auto" }, { children: children }))); } else if (isPressureOperation) { return (_jsx(LinearGradient, Object.assign({ colors: ['rgba(0, 70, 140, 0.7)', 'rgba(0, 120, 200, 0.5)', 'rgba(173, 216, 230, 0.2)'], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: styles.card, pointerEvents: "auto" }, { children: children }))); } return _jsx(View, Object.assign({ style: [styles.card, theme === 'dark' && styles.cardDark] }, { children: children })); }; // Progress steps: 4 for write, 3 for read const isWriteCard = isSolenoidOperation || isTimeSetOperation; const progressSteps = isWriteCard ? [ { label: 'Write', active: operation.state !== 'IDLE' && operation.state !== 'ERROR' }, { label: 'Update', active: ['READ_READY', 'READ_PENDING', 'PROCESSING', 'READ_READY_READ', 'READ_READY_WRITE'].includes(operation.state) }, { label: 'Get', active: ['READ_PENDING', 'PROCESSING', 'READ_READY_WRITE'].includes(operation.state) }, { label: operation.state === 'PROCESSING' ? 'Processing' : 'Done', active: operation.state === 'PROCESSING' || operation.lastOperation.status === 'COMPLETED' } ] : [ { label: 'Read', active: operation.state !== 'IDLE' && operation.state !== 'ERROR' }, { label: 'Get', active: ['READ_PENDING', 'PROCESSING', 'READ_READY_WRITE'].includes(operation.state) }, { label: operation.state === 'PROCESSING' ? 'Processing' : 'Done', active: operation.state === 'PROCESSING' || operation.lastOperation.status === 'COMPLETED' } ]; return (_jsxs(CardWrapper, { children: [_jsxs(View, Object.assign({ style: styles.cardHeader }, { children: [_jsx(Text, Object.assign({ style: [styles.cardTitle, theme === 'dark' && styles.cardTitleDark] }, { children: translate(`${config.icon} ${config.displayName}`) })), _jsxs(View, Object.assign({ style: [styles.statusBadge, { backgroundColor: getStatusColor(operation.state) }] }, { children: [" ", _jsx(Text, Object.assign({ style: styles.statusText }, { children: operation.state.replace('_', ' ') })), " "] }))] })), _jsx(View, Object.assign({ style: [styles.progressContainer, disabled && styles.progressContainerInactive] }, { children: progressSteps.map((step, idx) => (_jsxs(React.Fragment, { children: [_jsxs(View, Object.assign({ style: styles.progressStep }, { children: [_jsx(View, Object.assign({ style: [styles.progressDot, step.active ? styles.progressDotActive : styles.progressDotInactive, step.label === 'Processing' ? styles.progressDotProcessing : (step.label === 'Done' && step.active) ? styles.progressDotComplete : null] }, { children: _jsx(Text, Object.assign({ style: styles.progressDotText }, { children: step.label === 'Processing' ? '🔄' : step.label === 'Done' && step.active ? '✓' : idx + 1 })) })), _jsx(Text, Object.assign({ style: styles.progressLabel }, { children: step.label }))] })), idx < progressSteps.length - 1 && _jsx(View, { style: styles.progressLine })] }, step.label))) })), operation.data && (_jsx(View, Object.assign({ style: [styles.dataContainer, theme === 'dark' && styles.dataContainerDark] }, { children: _jsx(Text, Object.assign({ style: [styles.dataText, theme === 'dark' && styles.dataTextDark] }, { children: operation.data })) }))), _jsxs(TouchableOpacity, Object.assign({ style: [styles.operationButton, { backgroundColor: getStatusColor(operation.state) }, disabled && styles.operationButtonDisabled], onPress: onPress, disabled: disabled }, { children: [(operation.state === 'WRITE_PENDING' || operation.state === 'READ_PENDING') && (_jsx(ActivityIndicator, { size: "small", color: "#fff", style: styles.buttonLoader })), _jsx(Text, Object.assign({ style: styles.operationButtonText }, { children: getButtonText() }))] }))] })); }; const styles = StyleSheet.create({ card: { backgroundColor: '#fff', borderRadius: 12, padding: 16, marginBottom: 16, borderWidth: 1, borderColor: '#e0e0e0', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, cardDark: { backgroundColor: '#2a2a2a', borderColor: '#444', }, cardInactive: { opacity: 0.6, }, cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, }, cardTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', flex: 1, }, cardTitleDark: { color: '#fff', }, statusBadge: { paddingHorizontal: 8, paddingVertical: 4, borderRadius: 12, minWidth: 80, alignItems: 'center', }, statusText: { color: '#fff', fontSize: 10, fontWeight: 'bold', textTransform: 'uppercase', }, progressContainer: { flexDirection: 'row', alignItems: 'center', marginBottom: 12, }, progressContainerInactive: { opacity: 0.5, }, progressStep: { alignItems: 'center', flex: 1, }, progressDot: { width: 24, height: 24, borderRadius: 12, backgroundColor: '#e0e0e0', alignItems: 'center', justifyContent: 'center', marginBottom: 4, }, progressDotActive: { backgroundColor: '#007bff', }, progressDotProcessing: { backgroundColor: '#ffc107', }, progressDotComplete: { backgroundColor: '#28a745', }, progressDotInactive: { backgroundColor: '#e0e0e0', }, progressDotText: { color: '#fff', fontSize: 10, fontWeight: 'bold', }, progressLabel: { fontSize: 10, color: '#666', textAlign: 'center', }, progressLine: { height: 2, backgroundColor: '#e0e0e0', flex: 1, marginHorizontal: 8, }, dataContainer: { backgroundColor: '#f8f9fa', padding: 12, borderRadius: 8, marginBottom: 12, }, dataContainerDark: { backgroundColor: '#333', }, dataText: { fontSize: 14, color: '#333', fontFamily: 'monospace', }, dataTextDark: { color: '#fff', }, operationButton: { padding: 12, borderRadius: 8, alignItems: 'center', flexDirection: 'row', justifyContent: 'center', }, operationButtonDisabled: { opacity: 0.5, }, operationButtonText: { color: '#fff', fontSize: 14, fontWeight: 'bold', }, buttonLoader: { marginRight: 8, }, }); export default NfcOperationCard;