All files / src/components/monitors MonitorForm.tsx

100% Statements 76/76
100% Branches 15/15
100% Functions 5/5
100% Lines 76/76

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1031x                             34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x   34x 9x 9x 8x 8x 8x 8x 8x 9x   34x 34x 34x 34x   34x 34x 34x 34x 34x 34x 34x 34x 34x 34x   34x 34x   34x 34x 34x 34x 34x   34x 34x 34x 34x 34x 34x 34x   34x 34x 34x 34x 34x 34x 34x 34x 34x   34x 34x   34x 34x 34x 34x 34x   34x 34x 34x 34x 34x 34x 34x   34x 34x 34x   34x  
import { useState } from "react";
 
interface MonitorFormData {
  url: string;
  interval_seconds: number;
  is_active: boolean;
}
 
interface MonitorFormProps {
  onSubmit: (data: MonitorFormData) => void;
  onCancel: () => void;
  initialData?: Partial<MonitorFormData>;
  isLoading?: boolean;
}
 
export default function MonitorForm({
  onSubmit,
  onCancel,
  initialData,
  isLoading,
}: MonitorFormProps) {
  const [url, setUrl] = useState(initialData?.url || "");
  const [interval, setInterval] = useState(
    initialData?.interval_seconds || 300,
  );
  const [isActive, setIsActive] = useState(initialData?.is_active ?? true);
 
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!url.trim()) return;
    onSubmit({
      url: url.trim(),
      interval_seconds: interval,
      is_active: isActive,
    });
  };
 
  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">
          URL to Monitor
        </label>
        <input
          type="url"
          value={url}
          onChange={(e) => setUrl(e.target.value)}
          placeholder="https://example.com"
          className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
          required
        />
      </div>
 
      <div>
        <label className="block text-sm font-medium text-gray-700 mb-1">
          Check Interval (seconds)
        </label>
        <select
          value={interval}
          onChange={(e) => setInterval(Number(e.target.value))}
          className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer"
        >
          <option value={60}>1 minute</option>
          <option value={300}>5 minutes</option>
          <option value={900}>15 minutes</option>
          <option value={1800}>30 minutes</option>
          <option value={3600}>1 hour</option>
        </select>
      </div>
 
      <div className="flex items-center gap-2">
        <input
          type="checkbox"
          id="isActive"
          checked={isActive}
          onChange={(e) => setIsActive(e.target.checked)}
          className="rounded border-gray-300 cursor-pointer"
        />
        <label htmlFor="isActive" className="text-sm text-gray-700">
          Active
        </label>
      </div>
 
      <div className="flex gap-3 pt-2">
        <button
          type="submit"
          disabled={isLoading}
          className="flex-1 rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50 cursor-pointer"
        >
          {isLoading ? "Saving..." : "Save Monitor"}
        </button>
        <button
          type="button"
          onClick={onCancel}
          className="rounded-md border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 cursor-pointer"
        >
          Cancel
        </button>
      </div>
    </form>
  );
}