132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
// src/ui/pages/Settings/ChangePasswordModal.tsx
|
|
import React, { useState } from "react";
|
|
import { Eye, EyeOff } from "lucide-react";
|
|
|
|
interface ChangePasswordModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({
|
|
isOpen,
|
|
onClose,
|
|
}) => {
|
|
const [oldPassword, setOldPassword] = useState("");
|
|
const [newPassword, setNewPassword] = useState("");
|
|
const [confirmPassword, setConfirmPassword] = useState("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (newPassword !== confirmPassword) {
|
|
alert("New passwords do not match!");
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
try {
|
|
const payload = {
|
|
oldPassword,
|
|
password: newPassword,
|
|
cPassword: confirmPassword,
|
|
};
|
|
|
|
// 🔗 Call the Electron bridge function
|
|
const response = await window.electron.changePassword(payload);
|
|
|
|
if (response.success) {
|
|
alert("Password changed successfully!");
|
|
onClose();
|
|
} else {
|
|
alert(response.message || "Failed to change password.");
|
|
}
|
|
} catch (error) {
|
|
console.error("Password change error:", error);
|
|
alert("Error changing password.");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<dialog open className="modal modal-open">
|
|
<div className="modal-box w-96">
|
|
<h3 className="font-bold text-lg mb-3">Change Password</h3>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-3">
|
|
{/* Old Password */}
|
|
<div>
|
|
<label className="label text-xs font-medium">Current Password</label>
|
|
<input
|
|
type={showPassword ? "text" : "password"}
|
|
className="input input-bordered w-full"
|
|
value={oldPassword}
|
|
onChange={(e) => setOldPassword(e.target.value)}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
{/* New Password */}
|
|
<div>
|
|
<label className="label text-xs font-medium">New Password</label>
|
|
<div className="relative">
|
|
<input
|
|
type={showPassword ? "text" : "password"}
|
|
className="input input-bordered w-full pr-10"
|
|
value={newPassword}
|
|
onChange={(e) => setNewPassword(e.target.value)}
|
|
required
|
|
/>
|
|
<button
|
|
type="button"
|
|
className="absolute right-2 top-2 text-gray-500"
|
|
onClick={() => setShowPassword(!showPassword)}
|
|
>
|
|
{showPassword ? <EyeOff size={16} /> : <Eye size={16} />}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Confirm Password */}
|
|
<div>
|
|
<label className="label text-xs font-medium">Confirm New Password</label>
|
|
<input
|
|
type={showPassword ? "text" : "password"}
|
|
className="input input-bordered w-full"
|
|
value={confirmPassword}
|
|
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="modal-action">
|
|
<button
|
|
type="button"
|
|
className="btn btn-sm btn-ghost"
|
|
onClick={onClose}
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className={`btn btn-sm btn-primary ${loading ? "loading" : ""}`}
|
|
>
|
|
{loading ? "Updating..." : "Update"}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<form method="dialog" className="modal-backdrop" onClick={onClose}>
|
|
<button>close</button>
|
|
</form>
|
|
</dialog>
|
|
);
|
|
};
|
|
|
|
export default ChangePasswordModal;
|