Fix: Use correct API endpoint for test email
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@@ -7,8 +6,9 @@ import { Label } from "@/components/ui/label";
|
|||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { useLanguage } from "@/contexts/LanguageContext";
|
import { useLanguage } from "@/contexts/LanguageContext";
|
||||||
import { Mail, X } from "lucide-react";
|
import { Mail, X, AlertCircle, CheckCircle, Loader2 } from "lucide-react";
|
||||||
import { toast } from "@/hooks/use-toast";
|
import { toast } from "@/hooks/use-toast";
|
||||||
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
|
|
||||||
interface TestEmailDialogProps {
|
interface TestEmailDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -33,9 +33,16 @@ const TestEmailDialog: React.FC<TestEmailDialogProps> = ({
|
|||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [template, setTemplate] = useState('verification');
|
const [template, setTemplate] = useState('verification');
|
||||||
const [collection, setCollection] = useState('_superusers');
|
const [collection, setCollection] = useState('_superusers');
|
||||||
|
const [lastResult, setLastResult] = useState<{ success: boolean; message: string } | null>(null);
|
||||||
|
const [isInternalTesting, setIsInternalTesting] = useState(false);
|
||||||
|
|
||||||
|
const validateEmail = (email: string): boolean => {
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
return emailRegex.test(email);
|
||||||
|
};
|
||||||
|
|
||||||
const handleSend = async () => {
|
const handleSend = async () => {
|
||||||
if (!email) {
|
if (!email.trim()) {
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Please enter an email address",
|
description: "Please enter an email address",
|
||||||
@@ -44,39 +51,73 @@ const TestEmailDialog: React.FC<TestEmailDialogProps> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!validateEmail(email)) {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: "Please enter a valid email address",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
setLastResult(null);
|
||||||
|
setIsInternalTesting(true);
|
||||||
|
|
||||||
|
console.log('Sending test email with data:', {
|
||||||
|
email,
|
||||||
|
template,
|
||||||
|
collection: template === 'verification' || template === 'password-reset' ? collection : undefined
|
||||||
|
});
|
||||||
|
|
||||||
await onSendTest({
|
await onSendTest({
|
||||||
email,
|
email,
|
||||||
template,
|
template,
|
||||||
collection: template === 'verification' ? collection : undefined
|
collection: template === 'verification' || template === 'password-reset' ? collection : undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
setLastResult({
|
||||||
|
success: true,
|
||||||
|
message: `Test email sent successfully to ${email}`
|
||||||
});
|
});
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "Test email sent successfully",
|
description: `Test email sent successfully to ${email}`,
|
||||||
variant: "default",
|
variant: "default",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close dialog on success
|
|
||||||
handleClose();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error sending test email:', error);
|
console.error('Error sending test email:', error);
|
||||||
|
const errorMessage = error instanceof Error ? error.message : "Failed to send test email";
|
||||||
|
|
||||||
|
setLastResult({
|
||||||
|
success: false,
|
||||||
|
message: errorMessage
|
||||||
|
});
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to send test email",
|
description: errorMessage,
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
setIsInternalTesting(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
// Reset form
|
// Reset form but keep last result for reference
|
||||||
setEmail('');
|
setEmail('');
|
||||||
setTemplate('verification');
|
setTemplate('verification');
|
||||||
setCollection('_superusers');
|
setCollection('_superusers');
|
||||||
|
// Don't reset lastResult immediately to allow user to see the result
|
||||||
|
setTimeout(() => setLastResult(null), 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isLoading = isTesting || isInternalTesting;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogContent className="sm:max-w-md">
|
<DialogContent className="sm:max-w-md">
|
||||||
@@ -90,16 +131,31 @@ const TestEmailDialog: React.FC<TestEmailDialogProps> = ({
|
|||||||
size="icon"
|
size="icon"
|
||||||
className="absolute right-4 top-4"
|
className="absolute right-4 top-4"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="space-y-4 py-4">
|
<div className="space-y-4 py-4">
|
||||||
|
{/* Show last result */}
|
||||||
|
{lastResult && (
|
||||||
|
<Alert variant={lastResult.success ? "default" : "destructive"}>
|
||||||
|
{lastResult.success ? (
|
||||||
|
<CheckCircle className="h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<AlertCircle className="h-4 w-4" />
|
||||||
|
)}
|
||||||
|
<AlertDescription>
|
||||||
|
{lastResult.message}
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Template Selection */}
|
{/* Template Selection */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<Label>{t("emailTemplate", "settings")}</Label>
|
<Label>{t("emailTemplate", "settings")}</Label>
|
||||||
<RadioGroup value={template} onValueChange={setTemplate}>
|
<RadioGroup value={template} onValueChange={setTemplate} disabled={isLoading}>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<RadioGroupItem value="verification" id="verification" />
|
<RadioGroupItem value="verification" id="verification" />
|
||||||
<Label htmlFor="verification">{t("verification", "settings")}</Label>
|
<Label htmlFor="verification">{t("verification", "settings")}</Label>
|
||||||
@@ -112,22 +168,14 @@ const TestEmailDialog: React.FC<TestEmailDialogProps> = ({
|
|||||||
<RadioGroupItem value="email-change" id="email-change" />
|
<RadioGroupItem value="email-change" id="email-change" />
|
||||||
<Label htmlFor="email-change">{t("confirmEmailChange", "settings")}</Label>
|
<Label htmlFor="email-change">{t("confirmEmailChange", "settings")}</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<RadioGroupItem value="otp" id="otp" />
|
|
||||||
<Label htmlFor="otp">{t("otp", "settings")}</Label>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<RadioGroupItem value="login-alert" id="login-alert" />
|
|
||||||
<Label htmlFor="login-alert">{t("loginAlert", "settings")}</Label>
|
|
||||||
</div>
|
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Auth Collection - only show for verification template */}
|
{/* Auth Collection - show for verification and password-reset templates */}
|
||||||
{template === 'verification' && (
|
{(template === 'verification' || template === 'password-reset') && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>{t("authCollection", "settings")} *</Label>
|
<Label>{t("authCollection", "settings")} *</Label>
|
||||||
<Select value={collection} onValueChange={setCollection}>
|
<Select value={collection} onValueChange={setCollection} disabled={isLoading}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder={t("selectCollection", "settings")} />
|
<SelectValue placeholder={t("selectCollection", "settings")} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -148,21 +196,34 @@ const TestEmailDialog: React.FC<TestEmailDialogProps> = ({
|
|||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
placeholder={t("enterEmailAddress", "settings")}
|
placeholder={t("enterEmailAddress", "settings")}
|
||||||
required
|
required
|
||||||
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Info message */}
|
||||||
|
<Alert>
|
||||||
|
<AlertCircle className="h-4 w-4" />
|
||||||
|
<AlertDescription>
|
||||||
|
This will send a test email using your configured SMTP settings. Make sure SMTP is properly configured first.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter className="flex justify-between">
|
<DialogFooter className="flex justify-between">
|
||||||
<Button variant="outline" onClick={handleClose}>
|
<Button variant="outline" onClick={handleClose} disabled={isLoading}>
|
||||||
{t("close", "common")}
|
{t("close", "common")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleSend}
|
onClick={handleSend}
|
||||||
disabled={!email || isTesting}
|
disabled={!email || isLoading}
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
|
) : (
|
||||||
<Mail className="h-4 w-4" />
|
<Mail className="h-4 w-4" />
|
||||||
{isTesting ? t("sending", "settings") : t("send", "common")}
|
)}
|
||||||
|
{isLoading ? t("sending", "settings") : t("send", "common")}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
Reference in New Issue
Block a user