194 lines
8.4 KiB
TypeScript
194 lines
8.4 KiB
TypeScript
import { useForm } from "@tanstack/react-form";
|
|
import { useNavigate } from "@tanstack/react-router";
|
|
import axios from "axios";
|
|
import { useState } from "react";
|
|
import { toast } from "sonner";
|
|
import { LstCard } from "../extendedUI/LstCard";
|
|
import { CardContent, CardHeader } from "../ui/card";
|
|
|
|
import { Label } from "../ui/label";
|
|
import { Input } from "../ui/input";
|
|
import { Button } from "../ui/button";
|
|
|
|
export default function PasswordChange() {
|
|
const [saving, setSaving] = useState(false);
|
|
const token = localStorage.getItem("auth_token");
|
|
const navigate = useNavigate();
|
|
|
|
const form = useForm({
|
|
defaultValues: {
|
|
password: "",
|
|
confirmPassword: "",
|
|
},
|
|
onSubmit: async ({ value }) => {
|
|
setSaving(true);
|
|
try {
|
|
const res = await axios.patch("/api/auth/profile", value, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
});
|
|
|
|
//console.log(res.data);
|
|
|
|
if (res.data.success) {
|
|
localStorage.removeItem("auth_token");
|
|
navigate({ to: "/login" });
|
|
form.reset();
|
|
toast.success(`Your password was just updated.`);
|
|
setSaving(false);
|
|
}
|
|
|
|
if (!res.data.success) {
|
|
toast.error(res.data.message);
|
|
setSaving(false);
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
toast.error("There was an error updating your password");
|
|
setSaving(false);
|
|
}
|
|
},
|
|
});
|
|
|
|
return (
|
|
<div>
|
|
<LstCard className="w-96 ml-7">
|
|
<CardHeader>
|
|
<p>Password Change Form</p>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<form
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}}
|
|
>
|
|
<form.Field
|
|
name="password"
|
|
// We can choose between form-wide and field-specific validators
|
|
validators={{
|
|
onChangeAsyncDebounceMs: 500,
|
|
onChangeAsync: ({ value }) => {
|
|
// if (
|
|
// window.location.pathname.includes(
|
|
// "/users"
|
|
// ) &&
|
|
// value.length === 0
|
|
// ) {
|
|
// return;
|
|
// }
|
|
if (value.length < 4) {
|
|
return "Password must be at least 4 characters long.";
|
|
}
|
|
|
|
if (!/[A-Z]/.test(value)) {
|
|
return "Password must contain at least one uppercase letter.";
|
|
}
|
|
|
|
if (!/[a-z]/.test(value)) {
|
|
return "Password must contain at least one lower case letter.";
|
|
}
|
|
|
|
if (!/[0-9]/.test(value)) {
|
|
return "Password must contain at least one number.";
|
|
}
|
|
|
|
if (
|
|
!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(
|
|
value
|
|
)
|
|
) {
|
|
return "Password must contain at least one special character.";
|
|
}
|
|
},
|
|
}}
|
|
children={(field) => {
|
|
return (
|
|
<div className="m-2 min-w-48 max-w-96 p-2">
|
|
<Label
|
|
htmlFor="password1"
|
|
className="mb-2"
|
|
>
|
|
Password
|
|
</Label>
|
|
<Input
|
|
name={field.name}
|
|
value={field.state.value}
|
|
onBlur={field.handleBlur}
|
|
type="password"
|
|
onChange={(e) =>
|
|
field.handleChange(
|
|
e.target.value
|
|
)
|
|
}
|
|
/>
|
|
{field.state.meta.errors.length ? (
|
|
<em>
|
|
{field.state.meta.errors.join(
|
|
","
|
|
)}
|
|
</em>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}}
|
|
/>
|
|
|
|
<form.Field
|
|
name="confirmPassword"
|
|
validators={{
|
|
onChange: ({ value, fieldApi }) => {
|
|
const password =
|
|
fieldApi.form.getFieldValue("password");
|
|
if (value !== password) {
|
|
return "Passwords do not match.";
|
|
}
|
|
},
|
|
}}
|
|
>
|
|
{(field) => {
|
|
return (
|
|
<div className="m-2 min-w-48 max-w-96 p-2">
|
|
<Label
|
|
htmlFor="confirmPassword"
|
|
className="mb-2"
|
|
>
|
|
Confirm Password
|
|
</Label>
|
|
<Input
|
|
name={field.name}
|
|
value={field.state.value}
|
|
onBlur={field.handleBlur}
|
|
type="password"
|
|
onChange={(e) =>
|
|
field.handleChange(
|
|
e.target.value
|
|
)
|
|
}
|
|
/>
|
|
{field.state.meta.errors.length ? (
|
|
<em>
|
|
{field.state.meta.errors.join(
|
|
", "
|
|
)}
|
|
</em>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}}
|
|
</form.Field>
|
|
<div className="mt-4 ml-4 flex justify-end">
|
|
<Button
|
|
type="submit"
|
|
onClick={form.handleSubmit}
|
|
disabled={saving}
|
|
>
|
|
Save
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</CardContent>
|
|
</LstCard>
|
|
</div>
|
|
);
|
|
}
|