frontendsrccomponentsCronJobTable.js:
import React, { useState } from 'react';
import { Table, Button, Form, InputGroup, Col } from 'react-bootstrap';
function CronJobTable() {
const [cronJobs, setCronJobs] = useState([]);
const [newCronJob, setNewCronJob] = useState({
minute: '',
hour: '',
day: '',
month: '',
weekday: '',
command: '',
});
const [validationErrors, setValidationErrors] = useState({});
const handleInputChange = (e) => {
setNewCronJob({ ...newCronJob, [e.target.name]: e.target.value });
setValidationErrors({ ...validationErrors, [e.target.name]: '' }); // Clear error on change
};
const validateCronExpression = (expression, fieldName) => {
// You can implement a more robust validation using a cron parsing library here
// For now, let's do a basic check for allowed characters and ranges
const allowedChars = /[*,/-0-9]/;
if (!allowedChars.test(expression)) {
setValidationErrors({ ...validationErrors, [fieldName]: 'Invalid characters' });
return false;
}
return true;
};
const addCronJob = () => {
const isValidMinute = validateCronExpression(newCronJob.minute, 'minute');
const isValidHour = validateCronExpression(newCronJob.hour, 'hour');
const isValidDay = validateCronExpression(newCronJob.day, 'day');
const isValidMonth = validateCronExpression(newCronJob.month, 'month');
const isValidWeekday = validateCronExpression(newCronJob.weekday, 'weekday');
if (isValidMinute && isValidHour && isValidDay && isValidMonth && isValidWeekday) {
setCronJobs([...cronJobs, newCronJob]);
setNewCronJob({
minute: '',
hour: '',
day: '',
month: '',
weekday: '',
command: '',
});
setValidationErrors({}); // Clear all errors
}
};
const deleteCronJob = (index) => {
setCronJobs(cronJobs.filter((_, i) => i !== index));
};
return (
<div>
<h2>Add New Cron Job</h2>
<Form>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>Minute:</Form.Label>
<Form.Control
type="text"
name="minute"
value={newCronJob.minute}
onChange={handleInputChange}
isInvalid={!!validationErrors.minute}
/>
<Form.Control.Feedback type="invalid">
{validationErrors.minute}
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Hour:</Form.Label>
<Form.Control
type="text"
name="hour"
value={newCronJob.hour}
onChange={handleInputChange}
isInvalid={!!validationErrors.hour}
/>
<Form.Control.Feedback type="invalid">
{validationErrors.hour}
</Form.Control.Feedback>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>Day:</Form.Label>
<Form.Control
type="text"
name="day"
value={newCronJob.day}
onChange={handleInputChange}
isInvalid={!!validationErrors.day}
/>
<Form.Control.Feedback type="invalid">
{validationErrors.day}
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Month:</Form.Label>
<Form.Control
type="text"
name="month"
value={newCronJob.month}
onChange={handleInputChange}
isInvalid={!!validationErrors.month}
/>
<Form.Control.Feedback type="invalid">
{validationErrors.month}
</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Weekday:</Form.Label>
<Form.Control
type="text"
name="weekday"
value={newCronJob.weekday}
onChange={handleInputChange}
isInvalid={!!validationErrors.weekday}
/>
<Form.Control.Feedback type="invalid">
{validationErrors.weekday}
</Form.Control.Feedback>
</Form.Group>
</Form.Row>
<Form.Group>
<Form.Label>Command:</Form.Label>
<Form.Control
type="text"
name="command"
value={newCronJob.command}
onChange={handleInputChange}
/>
</Form.Group>
<Button variant="primary" onClick={addCronJob}>
Add New Cron Job
</Button>
</Form>
<br />
<h2>Current Cron Jobs</h2>
<Table striped bordered hover>
<thead>
<tr>
<th>Minute</th>
<th>Hour</th>
<th>Day</th>
<th>Month</th>
<th>Weekday</th>
<th>Command</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{cronJobs.map((cronJob, index) => (
<tr key={index}>
<td>{cronJob.minute}</td>
<td>{cronJob.hour}</td>
<td>{cronJob.day}</td>
<td>{cronJob.month}</td>
<td>{cronJob.weekday}</td>
<td>{cronJob.command}</td>
<td>
<Button variant="danger" onClick={() => deleteCronJob(index)}>
Delete
</Button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
}
export default CronJobTable;
Then in the calling file frontendsrcpagesmainApp.js I do:
import CronJobTable from "../components/CronJobTable";
And I get the error on the React frontend:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined. You
likely forgot to export your component from the file it’s defined in,
or you might have mixed up default and named imports.Check the render method of `CronJobTable`. Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of `CronJobTable`. at createFiberFromTypeAndProps (http://192.168.1.34:3000/static/js/bundle.js:76423:21) at createFiberFromElement (http://192.168.1.34:3000/static/js/bundle.js:76444:19) at createChild (http://192.168.1.34:3000/static/js/bundle.js:65013:32) at reconcileChildrenArray (http://192.168.1.34:3000/static/js/bundle.js:65253:29) at reconcileChildFibers (http://192.168.1.34:3000/static/js/bundle.js:65595:20) at reconcileChildren (http://192.168.1.34:3000/static/js/bundle.js:68527:32) at updateHostComponent (http://192.168.1.34:3000/static/js/bundle.js:69171:7) at beginWork (http://192.168.1.34:3000/static/js/bundle.js:70616:18) at HTMLUnknownElement.callCallback (http://192.168.1.34:3000/static/js/bundle.js:55602:18) at Object.invokeGuardedCallbackDev (http://192.168.1.34:3000/static/js/bundle.js:55646:20)