| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import { useFormState } from "react-use-form-state";
- import { Flex } from "rebass/styled-components";
- import React, { FC, useState } from "react";
- import styled from "styled-components";
- import getConfig from "next/config";
- import { useStoreState, useStoreActions } from "../../store";
- import { Domain } from "../../store/settings";
- import { errorMessage } from "../../utils";
- import { useMessage } from "../../hooks";
- import Text, { H2, Span } from "../Text";
- import { Colors } from "../../consts";
- import { TextInput } from "../Input";
- import { Button } from "../Button";
- import { Col } from "../Layout";
- import Table from "../Table";
- import Modal from "../Modal";
- import Icon from "../Icon";
- const { publicRuntimeConfig } = getConfig();
- const Th = styled(Flex).attrs({ as: "th", py: 3, px: 3 })`
- font-size: 15px;
- `;
- const Td = styled(Flex).attrs({ as: "td", py: 12, px: 3 })`
- font-size: 15px;
- `;
- const SettingsDomain: FC = () => {
- const { saveDomain, deleteDomain } = useStoreActions((s) => s.settings);
- const [domainToDelete, setDomainToDelete] = useState<Domain>(null);
- const [deleteLoading, setDeleteLoading] = useState(false);
- const domains = useStoreState((s) => s.settings.domains);
- const [message, setMessage] = useMessage(2000);
- const [loading, setLoading] = useState(false);
- const [modal, setModal] = useState(false);
- const [formState, { label, text }] = useFormState<{
- address: string;
- homepage: string;
- }>(null, { withIds: true });
- const onSubmit = async (e) => {
- e.preventDefault();
- setLoading(true);
- try {
- await saveDomain(formState.values);
- } catch (err) {
- setMessage(err?.response?.data?.error || "Couldn't add domain.");
- }
- formState.clear();
- setLoading(false);
- };
- const closeModal = () => {
- setDomainToDelete(null);
- setModal(false);
- };
- const onDelete = async () => {
- setDeleteLoading(true);
- await deleteDomain(domainToDelete.id).catch((err) =>
- setMessage(errorMessage(err, "Couldn't delete the domain."))
- );
- setMessage("Domain has been deleted successfully.", "green");
- closeModal();
- setDeleteLoading(false);
- };
- return (
- <Col alignItems="flex-start" maxWidth="100%">
- <H2 mb={4} bold>
- Custom domain
- </H2>
- <Text mb={3}>
- You can set a custom domain for your short URLs, so instead of{" "}
- <b>{publicRuntimeConfig.DEFAULT_DOMAIN}/shorturl</b> you can have{" "}
- <b>example.com/shorturl.</b>
- </Text>
- <Text mb={4}>
- Point your domain A record to <b>192.64.116.170</b> then add the domain
- via form below:
- </Text>
- {domains.length > 0 && (
- <Table my={3} scrollWidth="550px">
- <thead>
- <tr>
- <Th width={2 / 5}>Domain</Th>
- <Th width={2 / 5}>Homepage</Th>
- <Th width={1 / 5}></Th>
- </tr>
- </thead>
- <tbody>
- {domains.map((d) => (
- <tr key={d.address}>
- <Td width={2 / 5}>{d.address}</Td>
- <Td width={2 / 5}>
- {d.homepage || publicRuntimeConfig.DEFAULT_DOMAIN}
- </Td>
- <Td width={1 / 5} justifyContent="center">
- <Icon
- as="button"
- name="trash"
- stroke={Colors.TrashIcon}
- strokeWidth="2.5"
- backgroundColor={Colors.TrashIconBg}
- py={0}
- px={0}
- size={[23, 24]}
- p={["4px", "5px"]}
- onClick={() => {
- setDomainToDelete(d);
- setModal(true);
- }}
- />
- </Td>
- </tr>
- ))}
- </tbody>
- </Table>
- )}
- <Col
- alignItems="flex-start"
- onSubmit={onSubmit}
- width={1}
- as="form"
- my={[3, 4]}
- >
- <Flex width={1} flexDirection={["column", "row"]}>
- <Col mr={[0, 2]} mb={[3, 0]} flex="0 0 auto">
- <Text
- {...label("address")}
- as="label"
- mb={[2, 3]}
- fontSize={[15, 16]}
- bold
- >
- Domain:
- </Text>
- <TextInput
- {...text("address")}
- placeholder="example.com"
- maxWidth="240px"
- required
- />
- </Col>
- <Col ml={[0, 2]} flex="0 0 auto">
- <Text
- {...label("homepage")}
- as="label"
- mb={[2, 3]}
- fontSize={[15, 16]}
- bold
- >
- Homepage (optional):
- </Text>
- <TextInput
- {...text("homepage")}
- placeholder="Homepage URL"
- flex="1 1 auto"
- maxWidth="240px"
- />
- </Col>
- </Flex>
- <Button type="submit" color="purple" mt={[24, 3]} disabled={loading}>
- <Icon name={loading ? "spinner" : "plus"} mr={2} stroke="white" />
- {loading ? "Setting..." : "Set domain"}
- </Button>
- </Col>
- <Text color={message.color}>{message.text}</Text>
- <Modal id="delete-custom-domain" show={modal} closeHandler={closeModal}>
- <H2 mb={24} textAlign="center" bold>
- Delete domain?
- </H2>
- <Text textAlign="center">
- Are you sure do you want to delete the domain{" "}
- <Span bold>
- "{domainToDelete && domainToDelete.address}"
- </Span>
- ?
- </Text>
- <Flex justifyContent="center" mt={44}>
- {deleteLoading ? (
- <>
- <Icon name="spinner" size={20} stroke={Colors.Spinner} />
- </>
- ) : (
- <>
- <Button color="gray" mr={3} onClick={closeModal}>
- Cancel
- </Button>
- <Button color="red" ml={3} onClick={onDelete}>
- <Icon name="trash" stroke="white" mr={2} />
- Delete
- </Button>
- </>
- )}
- </Flex>
- </Modal>
- </Col>
- );
- };
- export default SettingsDomain;
|