Genesis
This commit is contained in:
173
src/client/RuleManager.js
Normal file
173
src/client/RuleManager.js
Normal file
@@ -0,0 +1,173 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Typography,
|
||||
Button,
|
||||
Paper,
|
||||
Divider
|
||||
} from '@mui/material';
|
||||
import RuleCard from './RuleCard';
|
||||
import RuleEditor from './RuleEditor';
|
||||
|
||||
// Initial mock rules for demonstration
|
||||
const initialRules = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Morning Light',
|
||||
enabled: true,
|
||||
trigger: {
|
||||
type: 'time',
|
||||
time: '06:30',
|
||||
days: ['mon', 'tue', 'wed', 'thu', 'fri']
|
||||
},
|
||||
action: {
|
||||
type: 'toggle',
|
||||
target: 'Workshop Light',
|
||||
state: true
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'High Humidity Fan',
|
||||
enabled: true,
|
||||
trigger: {
|
||||
type: 'sensor',
|
||||
sensor: 'Humidity',
|
||||
operator: '>',
|
||||
value: 70
|
||||
},
|
||||
action: {
|
||||
type: 'keepOn',
|
||||
target: 'Exhaust Fan',
|
||||
duration: 15
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Evening Shutdown',
|
||||
enabled: false,
|
||||
trigger: {
|
||||
type: 'time',
|
||||
time: '18:00',
|
||||
days: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
|
||||
},
|
||||
action: {
|
||||
type: 'toggle',
|
||||
target: 'All Outlets',
|
||||
state: false
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default function RuleManager() {
|
||||
const [rules, setRules] = useState(initialRules);
|
||||
const [editorOpen, setEditorOpen] = useState(false);
|
||||
const [editingRule, setEditingRule] = useState(null);
|
||||
|
||||
const handleAddRule = () => {
|
||||
setEditingRule(null);
|
||||
setEditorOpen(true);
|
||||
};
|
||||
|
||||
const handleEditRule = (rule) => {
|
||||
setEditingRule(rule);
|
||||
setEditorOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteRule = (ruleId) => {
|
||||
setRules(rules.filter(r => r.id !== ruleId));
|
||||
};
|
||||
|
||||
const handleToggleRule = (ruleId) => {
|
||||
setRules(rules.map(r =>
|
||||
r.id === ruleId ? { ...r, enabled: !r.enabled } : r
|
||||
));
|
||||
};
|
||||
|
||||
const handleSaveRule = (ruleData) => {
|
||||
if (editingRule) {
|
||||
// Update existing rule
|
||||
setRules(rules.map(r =>
|
||||
r.id === editingRule.id ? { ...r, ...ruleData } : r
|
||||
));
|
||||
} else {
|
||||
// Add new rule
|
||||
const newRule = {
|
||||
...ruleData,
|
||||
id: Math.max(0, ...rules.map(r => r.id)) + 1,
|
||||
enabled: true
|
||||
};
|
||||
setRules([...rules, newRule]);
|
||||
}
|
||||
setEditorOpen(false);
|
||||
setEditingRule(null);
|
||||
};
|
||||
|
||||
const handleCloseEditor = () => {
|
||||
setEditorOpen(false);
|
||||
setEditingRule(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper
|
||||
sx={{
|
||||
mt: 4,
|
||||
p: 3,
|
||||
background: 'linear-gradient(145deg, #3c3836 0%, #32302f 100%)',
|
||||
border: '1px solid #504945'
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
|
||||
<Box>
|
||||
<Typography variant="h5" sx={{ fontWeight: 600, display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
⚙️ Automation Rules
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Configure triggers and actions for home automation
|
||||
</Typography>
|
||||
</Box>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleAddRule}
|
||||
sx={{
|
||||
background: 'linear-gradient(45deg, #b8bb26 30%, #8ec07c 90%)',
|
||||
'&:hover': {
|
||||
background: 'linear-gradient(45deg, #c5c836 30%, #98c98a 90%)',
|
||||
}
|
||||
}}
|
||||
>
|
||||
+ Add Rule
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Divider sx={{ mb: 3 }} />
|
||||
|
||||
{rules.length === 0 ? (
|
||||
<Box sx={{ textAlign: 'center', py: 4 }}>
|
||||
<Typography color="text.secondary">
|
||||
No rules configured. Click "Add Rule" to create one.
|
||||
</Typography>
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
{rules.map(rule => (
|
||||
<RuleCard
|
||||
key={rule.id}
|
||||
rule={rule}
|
||||
onEdit={() => handleEditRule(rule)}
|
||||
onDelete={() => handleDeleteRule(rule.id)}
|
||||
onToggle={() => handleToggleRule(rule.id)}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<RuleEditor
|
||||
open={editorOpen}
|
||||
rule={editingRule}
|
||||
onSave={handleSaveRule}
|
||||
onClose={handleCloseEditor}
|
||||
/>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user