Untitled
unknown
plain_text
a year ago
14 kB
17
Indexable
"use client";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { CheckCircle } from "lucide-react";
import Image from "next/image";
import Modal from "@/components/ui/Modal";
import { GoogleButton } from "@/components/ui/GoogleButton";
import { MicrosoftButton } from "@/components/ui/MicrosoftButton";
import { apiService } from "@/services/api";
import { API_ENDPOINTS } from "@/constants/apiEndpoints";
import { useRouter } from "next/navigation";
import EmailCard from "@/components/ui/EmailCard";
import { useFormik } from "formik";
import * as Yup from "yup";
export default function EmailTab() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isSecondModalOpen, setIsSecondModalOpen] = useState(false);
const [linkedAccounts, setLinkedAccounts] = useState([]);
const [email, setEmail] = useState(""); // Store entered email
const [emailError, setEmailError] = useState("");
const router = useRouter();
const handleFormSubmit = async (values, { resetForm }) => {
const formattedValues = {
smtp_email: values.email,
smtp_username: values.username,
smtp_password: values.password,
smtp_port: Number(values.port), // ✅ Convert port to a number before submitting
smtp_host: values.host,
};
console.log("Form Submitted:", formattedValues);
try {
const response = await apiService.post(
API_ENDPOINTS.AUTH.SAVE_SMTP_LINKED_ACCOUNT,
formattedValues
);
if (response.data) {
resetForm(); // ✅ Reset Formik form
setEmail(""); // ✅ Reset email state
setEmailError(""); // ✅ Clear email error
setIsSecondModalOpen(false); // ✅ Close modal
}
} catch (error) {
console.error("Error saving SMTP linked account:", error);
}
};
const validationSchema = Yup.object({
email: Yup.string().email("Invalid email address").required("Email is required"),
password: Yup.string().required("Password is required"),
username: Yup.string(), // Optional
port: Yup.number()
.typeError("Port must be a number")
.integer("Port must be a whole number") // Ensures no decimals
.min(0, "Port must be at least 0")
.max(999999, "Port cannot exceed 6 digits") // Ensures a max of 6 digits
.required("Port is required"),
host: Yup.string()
.matches(
/^(?!:\/\/)([a-zA-Z0-9-_]+\.)+[a-zA-Z]{2,6}$/,
"Enter a valid domain"
)
.required("Host is required"),
});
const formik = useFormik({
initialValues: {
email: email || "",
username: "",
password: "",
port: "",
host: "",
},
validationSchema,
onSubmit: handleFormSubmit
});
const fetchEmail = async () => {
try {
const response = await apiService.get(API_ENDPOINTS.AUTH.GET_LINKED_ACCOUNTS)
if (response.data && Object.keys(response.data).length > 0) {
setLinkedAccounts(response.data);
}
} catch (error) {
console.error('Microsoft login error:', error);
// Toast error is already handled in api.js post method
}
}
const handleGoogleLogin = async () => {
try {
const response = await apiService.get(API_ENDPOINTS.AUTH.GOOGLE_LOGIN_DASHBOARD);
if (response.data) {
router.push(response.data)
}
} catch (error) {
console.error('Google login error:', error);
// Toast error is already handled in api.js post method
}
};
const handleMicrosoftLogin = async () => {
try {
// const response = await authService.microsoftLogin({
// company_domain:"pconsultinglimited"
// });
} catch (error) {
console.error('Microsoft login error:', error);
// Toast error is already handled in api.js post method
}
};
const handleNextClick = () => {
try {
// Validate only the email field
Yup.string()
.email("Invalid email address")
.required("Email is required")
.validateSync(email);
setEmailError(""); // Clear error if validation passes
setIsModalOpen(false);
setIsSecondModalOpen(true);
formik.setFieldValue("email", email);
} catch (err) {
setEmailError(err.message); // Show only email validation error
}
};
useEffect(() => {
fetchEmail();
}, []);
return (
<div className="p-6 pt-0 space-y-6">
{linkedAccounts.length === 0 ? (
// **Show this when there are no linked accounts**
<div className="flex items-start gap-6">
<div className="bg-purple-100 rounded-lg flex items-center justify-center">
<Image src="/images/email.png" alt="Email" width={91} height={102} />
</div>
<div className="space-y-2">
<h2 className="text-2xl font-semibold">Email</h2>
<p className="text-muted-foreground !mb-8">
Syncing your personal email will help you lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum
dolor.
</p>
<div className="space-y-8">
{[1, 2, 3].map((item) => (
<div key={item} className="flex gap-3">
<CheckCircle className="w-5 h-5 text-purple-500 mt-1" />
<div className="space-y-1">
<h3 className="font-medium">Schedule email</h3>
<p className="text-sm text-muted-foreground">
Schedule email along customized workflows. Schedule email along customized workflows.
{item === 2 && " Schedule email along customized workflows."}
</p>
</div>
</div>
))}
</div>
<div className="flex items-center gap-2 !mt-8">
<Button
className="bg-purple-500 hover:bg-purple-600 text-white"
onClick={() => setIsModalOpen(true)}
>
Sync email
</Button>
</div>
</div>
</div>
) : (
// **Show this when linked accounts exist**
<div className="p-6 space-y-6">
<h2 className="text-2xl font-semibold">Email</h2>
<p className="text-gray-600">
Syncing your personal email will help you lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor.
</p>
{/* Render Email Cards */}
<div className="flex gap-4">
{linkedAccounts.map((account, index) => (
<EmailCard
key={index}
email={account.connected_email}
type={account.provider_name || "Outlook"} // ✅ Use `provider_name`
status={account.linking_status}
lastSynced={account.updated_at || "10m"} // ✅ Use `updated_at`
isDefault={index === 0} // Assume first email is default
/>
))}
</div>
{/* Add Email Button */}
<Button onClick={() => setIsModalOpen(true)} className="bg-purple-500 hover:bg-purple-600 text-white mt-4">
Add another email ID
</Button>
</div>
)}
{/* ✅ Modal for Sync Email */}
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h2 className="text-xl font-semibold text-center mb-4">Connect your email ID</h2>
<div className="mb-6 w-full">
<GoogleButton className="w-full" onClick={handleGoogleLogin} />
</div>
<div className="mb-6 w-full">
<MicrosoftButton className="w-full" onClick={handleMicrosoftLogin} />
</div>
<div className="flex items-center my-4">
<div className="flex-grow h-px bg-gray-300"></div>
<span className="px-2 text-gray-500 orText">or</span>
<div className="flex-grow h-px bg-gray-300"></div>
</div>
<input
type="email"
placeholder="[email protected]"
className={`w-full border px-3 py-2 rounded-md mb-2 ${emailError ? "border-red-500" : ""}`}
value={email}
onChange={(e) => {
setEmail(e.target.value);
setEmailError(""); // Clear error when user starts typing
}}
/>
<div className="flex items-start w-full">
{emailError && <p className="text-red-500 text-xs mb-2">{emailError}</p>}
</div>
<button
className={`w-full py-2 rounded-md ${email && !emailError ? "bg-purple-500 text-white" : "bg-gray-300 text-gray-500 cursor-not-allowed"}`}
onClick={handleNextClick}
disabled={!email || !!emailError}
>
Next
</button>
</Modal>
<Modal isOpen={isSecondModalOpen} onClose={() => setIsSecondModalOpen(false)}>
<h2 className="text-xl font-semibold text-center mb-4">Connect your email ID</h2>
<form onSubmit={formik.handleSubmit} className="w-full">
{/* Email */}
<label className="block text-sm font-medium mb-1">Email ID *</label>
<input
type="email"
value={formik.values.email}
className="w-full border px-3 py-2 rounded-md mb-2"
onChange={formik.handleChange}
placeholder="[email protected]"
name="email"
/>
{formik.touched.email && formik.errors.email && (
<p className="text-red-500 text-xs">{formik.errors.email}</p>
)}
{/* Username (Optional) */}
<label className="block text-sm font-medium mb-1">Username</label>
<input
type="text"
name="username"
placeholder="Username"
className="w-full border px-3 py-2 rounded-md mb-2"
onChange={formik.handleChange}
value={formik.values.username}
/>
{/* Password */}
<label className="block text-sm font-medium mb-1">Password *</label>
<input
type="password"
name="password"
placeholder="Password"
className="w-full border px-3 py-2 rounded-md mb-2"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.password}
/>
{formik.touched.password && formik.errors.password && (
<p className="text-red-500 text-xs">{formik.errors.password}</p>
)}
{/* Port */}
<label className="block text-sm font-medium mb-1">Port *</label>
<input
type="text"
name="port"
placeholder="SMTP port number"
className="w-full border px-3 py-2 rounded-md mb-2"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.port}
/>
{formik.touched.port && formik.errors.port && (
<p className="text-red-500 text-xs">{formik.errors.port}</p>
)}
{/* Host */}
<label className="block text-sm font-medium mb-1">Host *</label>
<input
type="text"
name="host"
placeholder="yours.smtp.host.com"
className="w-full border px-3 py-2 rounded-md mb-2"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.host}
/>
{formik.touched.host && formik.errors.host && (
<p className="text-red-500 text-xs">{formik.errors.host}</p>
)}
{/* Submit Button */}
<button
type="submit"
className="w-full bg-purple-500 text-white py-2 rounded-md mt-4 disabled:bg-gray-400"
disabled={!formik.isValid || formik.isSubmitting}
>
Connect
</button>
</form>
</Modal>
</div>
);
}
Editor is loading...
Leave a Comment