url-password.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { useState } from "react";
  2. import { NextPage } from "next";
  3. import styled from "styled-components";
  4. import axios from "axios";
  5. import { Flex } from "reflexbox/styled-components";
  6. import { useFormState } from "react-use-form-state";
  7. import BodyWrapper from "../components/BodyWrapper";
  8. import TextInput from "../components/TextInput";
  9. import { Button } from "../components/Button";
  10. import Text from "../components/Text";
  11. interface Props {
  12. protectedLink?: string;
  13. }
  14. const UrlPasswordPage: NextPage<Props> = ({ protectedLink }) => {
  15. const [loading, setLoading] = useState(false);
  16. const [formState, { password }] = useFormState<{ password: string }>();
  17. const [error, setError] = useState<string>();
  18. const onSubmit = async e => {
  19. e.preventDefault();
  20. const { password } = formState.values;
  21. if (!password) {
  22. return setError("Password must not be empty.");
  23. }
  24. setError("");
  25. setLoading(true);
  26. // TODO: better api calls
  27. try {
  28. const { data } = await axios.post("/api/url/requesturl", {
  29. id: protectedLink,
  30. password
  31. });
  32. window.location.replace(data.target);
  33. } catch ({ response }) {
  34. setError(response.data.error);
  35. }
  36. setLoading(false);
  37. };
  38. return (
  39. <BodyWrapper>
  40. {!protectedLink ? (
  41. <Text as="h2" my={4} fontWeight={300}>
  42. 404 | Link could not be found.
  43. </Text>
  44. ) : (
  45. <Flex width={500} maxWidth="97%" flexDirection="column">
  46. <Text as="h2" fontWeight={700} my={3}>
  47. Protected link
  48. </Text>
  49. <Text as="p" mb={4}>
  50. Enter the password to be redirected to the link.
  51. </Text>
  52. <Flex
  53. as="form"
  54. alignItems="center"
  55. onSubmit={onSubmit}
  56. style={{ position: "relative" }}
  57. >
  58. <TextInput
  59. {...password("password")}
  60. placeholder="Password"
  61. height={[44, 54]}
  62. width={[1, 1 / 2]}
  63. mr={3}
  64. autoFocus
  65. required
  66. />
  67. <Button
  68. type="submit"
  69. icon={loading ? "loader" : ""}
  70. height={[40, 44]}
  71. >
  72. Go
  73. </Button>
  74. </Flex>
  75. <Text fontSize={14} color="red" fontWeight={400} mt={3}>
  76. {error}
  77. </Text>
  78. </Flex>
  79. )}
  80. </BodyWrapper>
  81. );
  82. };
  83. UrlPasswordPage.getInitialProps = async ({ req }) => {
  84. return {
  85. protectedLink: req && (req as any).protectedLink
  86. };
  87. };
  88. export default UrlPasswordPage;