SharePasswordFrame.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { useState } from "preact/hooks";
  2. import Input from "../components/form/Input.tsx";
  3. import Button from "../components/form/Button.tsx";
  4. import ThemeToggle from "./ThemeToggle.tsx";
  5. interface SharePasswordFormProps {
  6. id: string;
  7. title: string;
  8. }
  9. export default function SharePasswordFrame(props: SharePasswordFormProps) {
  10. const [password, setPassword] = useState("");
  11. const [error, setError] = useState(false);
  12. const handleSubmit = async () => {
  13. if (!password) {
  14. setError(true);
  15. return;
  16. }
  17. const resp = await fetch("/api/share/verify", {
  18. method: "POST",
  19. headers: { "Content-Type": "application/json" },
  20. body: JSON.stringify({ id: props.id, password }),
  21. });
  22. const respJson = await resp.json();
  23. if (respJson.success) {
  24. location.reload();
  25. } else {
  26. setError(true);
  27. }
  28. };
  29. return (
  30. <div className="flex flex-col items-center justify-center h-full">
  31. <div className="absolute top-4 right-4">
  32. <ThemeToggle />
  33. </div>
  34. <div className="w-[320px] max-w-[90%]">
  35. <h2 className="text-xl font-medium mb-1 text-center">{props.title}</h2>
  36. <p className="text-sm text-gray-500 dark:text-gray-400 mb-6 text-center">
  37. This post is password protected.
  38. </p>
  39. <Input
  40. type="password"
  41. placeholder="Enter password"
  42. error={error}
  43. value={password}
  44. onInput={(e) => {
  45. setError(false);
  46. setPassword((e.target as HTMLInputElement).value);
  47. }}
  48. onKeyDown={(e) => {
  49. if (e.key === "Enter") handleSubmit();
  50. }}
  51. />
  52. <Button
  53. type="button"
  54. variant="primary"
  55. className="w-full mt-3"
  56. onClick={handleSubmit}
  57. >
  58. View Post
  59. </Button>
  60. </div>
  61. </div>
  62. );
  63. }