All files / components/users DeactivateUserDialog.tsx

89.47% Statements 17/19
60% Branches 6/10
100% Functions 4/4
94.44% Lines 17/18

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 103 104 105 106 107 108 109 110 111 112 113 114                                                      119x 119x 119x   119x 2x 2x   2x 2x   2x 2x   2x 2x       2x       119x   119x                       1x                                                                 63x                                
/**
 * Deactivate user dialog component
 */
 
import { useState } from 'react';
import { AppDialog } from '@/components/common/AppDialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Loader2, AlertTriangle } from 'lucide-react';
import type { User } from '@/services/users.service';
import { handleApiError } from '@/lib/api';
 
interface DeactivateUserDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  user: User | null;
  onSubmit: (userId: string) => Promise<void>;
}
 
export default function DeactivateUserDialog({
  open,
  onOpenChange,
  user,
  onSubmit,
}: DeactivateUserDialogProps) {
  const [confirmation, setConfirmation] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
 
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    Iif (!user) return;
 
    setLoading(true);
    setError(null);
 
    try {
      await onSubmit(user.id);
      // Reset form
      setConfirmation('');
      onOpenChange(false);
    } catch (err) {
      setError(handleApiError(err));
    } finally {
      setLoading(false);
    }
  };
 
  const isFormValid = confirmation === user?.email;
 
  return (
    <AppDialog
      open={open}
      onOpenChange={onOpenChange}
      title="Deactivate User"
      description={`Deactivate ${user?.email}. Their data will be preserved but they will not be able to log in.`}
      className="max-w-md"
      footer={
        <>
          <Button
            type="button"
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={loading}
          >
            Cancel
          </Button>
          <Button
            type="submit"
            form="deactivate-user-form"
            disabled={loading || !isFormValid}
            variant="destructive"
          >
            {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            Deactivate User
          </Button>
        </>
      }
    >
      <form id="deactivate-user-form" onSubmit={handleSubmit} className="space-y-4">
        <Alert variant="destructive">
          <AlertTriangle className="h-4 w-4" />
          <AlertDescription>
            <strong>Warning:</strong> The user will not be able to log in while deactivated.
            Their data will be preserved and can be reactivated later by updating their status.
          </AlertDescription>
        </Alert>
 
        <div className="space-y-2">
          <Label htmlFor="confirmation">
            Type <code className="bg-muted px-1 py-0.5 rounded">{user?.email}</code> to confirm
          </Label>
          <Input
            id="confirmation"
            value={confirmation}
            onChange={(e) => setConfirmation(e.target.value)}
            placeholder={user?.email}
            required
            disabled={loading}
          />
        </div>
 
        {error && (
          <div className="text-sm text-destructive bg-destructive/10 p-3 rounded-md">
            {typeof error === 'string' ? error : JSON.stringify(error)}
          </div>
        )}
      </form>
    </AppDialog>
  );
}