kopia lustrzana https://github.com/bugout-dev/moonstream
				
				
				
			color selector
							rodzic
							
								
									e8222024d4
								
							
						
					
					
						commit
						aea00fb21e
					
				| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
import { React, useEffect, useState } from "react";
 | 
			
		||||
import {
 | 
			
		||||
  chakra,
 | 
			
		||||
  Box,
 | 
			
		||||
  Popover,
 | 
			
		||||
  PopoverTrigger,
 | 
			
		||||
  PopoverContent,
 | 
			
		||||
  PopoverHeader,
 | 
			
		||||
  PopoverBody,
 | 
			
		||||
  PopoverFooter,
 | 
			
		||||
  PopoverArrow,
 | 
			
		||||
  PopoverCloseButton,
 | 
			
		||||
  Portal,
 | 
			
		||||
  Stack,
 | 
			
		||||
  IconButton,
 | 
			
		||||
  Text,
 | 
			
		||||
  Input,
 | 
			
		||||
  useDisclosure,
 | 
			
		||||
  Button,
 | 
			
		||||
} from "@chakra-ui/react";
 | 
			
		||||
import { makeColor } from "../core/utils/makeColor";
 | 
			
		||||
import { BiRefresh } from "react-icons/bi";
 | 
			
		||||
import { GithubPicker } from "react-color";
 | 
			
		||||
 | 
			
		||||
const _ColorSelector = (props) => {
 | 
			
		||||
  const { onOpen, onClose, isOpen } = useDisclosure();
 | 
			
		||||
  const [color, setColor] = useState(props.initialColor ?? makeColor());
 | 
			
		||||
  const [triggerColor, setTriggerColor] = useState(color);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setTriggerColor(props.initialColor);
 | 
			
		||||
  }, [props.initialColor]);
 | 
			
		||||
 | 
			
		||||
  const handleChangeColorComplete = (color) => {
 | 
			
		||||
    setColor(color.hex);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleChangeColor = (event) => setColor(event.target.value);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Popover isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
 | 
			
		||||
      <PopoverTrigger>
 | 
			
		||||
        <Box
 | 
			
		||||
          {...props}
 | 
			
		||||
          placeSelf="center"
 | 
			
		||||
          boxSize="24px"
 | 
			
		||||
          borderRadius="sm"
 | 
			
		||||
          bgColor={triggerColor}
 | 
			
		||||
        ></Box>
 | 
			
		||||
      </PopoverTrigger>
 | 
			
		||||
      <Portal>
 | 
			
		||||
        <PopoverContent bg={"white.100"}>
 | 
			
		||||
          <PopoverArrow />
 | 
			
		||||
          <PopoverHeader>Change color</PopoverHeader>
 | 
			
		||||
          <PopoverCloseButton />
 | 
			
		||||
          <PopoverBody>
 | 
			
		||||
            <Stack direction="row" pb={2}>
 | 
			
		||||
              <Text fontWeight="600" alignSelf="center">
 | 
			
		||||
                Label color
 | 
			
		||||
              </Text>{" "}
 | 
			
		||||
              <IconButton
 | 
			
		||||
                size="md"
 | 
			
		||||
                // colorScheme="primary"
 | 
			
		||||
                color={"white.100"}
 | 
			
		||||
                _hover={{ bgColor: { color } }}
 | 
			
		||||
                bgColor={color}
 | 
			
		||||
                variant="outline"
 | 
			
		||||
                onClick={() => setColor(makeColor())}
 | 
			
		||||
                icon={<BiRefresh />}
 | 
			
		||||
              />
 | 
			
		||||
              <Input
 | 
			
		||||
                type="input"
 | 
			
		||||
                placeholder="color"
 | 
			
		||||
                name="color"
 | 
			
		||||
                value={color}
 | 
			
		||||
                onChange={handleChangeColor}
 | 
			
		||||
                w="200px"
 | 
			
		||||
                onSubmit={handleChangeColorComplete}
 | 
			
		||||
              ></Input>
 | 
			
		||||
            </Stack>
 | 
			
		||||
            <GithubPicker
 | 
			
		||||
              // color={this.state.background}
 | 
			
		||||
              onChangeComplete={handleChangeColorComplete}
 | 
			
		||||
            />
 | 
			
		||||
          </PopoverBody>
 | 
			
		||||
          <PopoverFooter>
 | 
			
		||||
            <Button
 | 
			
		||||
              onClick={() => {
 | 
			
		||||
                props.callback(color);
 | 
			
		||||
                onClose();
 | 
			
		||||
              }}
 | 
			
		||||
              colorScheme="suggested"
 | 
			
		||||
              variant="outline"
 | 
			
		||||
            >
 | 
			
		||||
              Apply
 | 
			
		||||
            </Button>
 | 
			
		||||
          </PopoverFooter>
 | 
			
		||||
        </PopoverContent>
 | 
			
		||||
      </Portal>
 | 
			
		||||
    </Popover>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const ColorSelector = chakra(_ColorSelector);
 | 
			
		||||
 | 
			
		||||
export default ColorSelector;
 | 
			
		||||
| 
						 | 
				
			
			@ -14,13 +14,17 @@ import {
 | 
			
		|||
  Button,
 | 
			
		||||
  ModalFooter,
 | 
			
		||||
  Spinner,
 | 
			
		||||
  IconButton,
 | 
			
		||||
} from "@chakra-ui/react";
 | 
			
		||||
import RadioCard from "./RadioCard";
 | 
			
		||||
import { useForm } from "react-hook-form";
 | 
			
		||||
 | 
			
		||||
import { GithubPicker } from "react-color";
 | 
			
		||||
import { BiRefresh } from "react-icons/bi";
 | 
			
		||||
import { makeColor } from "../core/utils/makeColor";
 | 
			
		||||
const NewSubscription = ({ isFreeOption, onClose }) => {
 | 
			
		||||
  const [color, setColor] = useState(makeColor());
 | 
			
		||||
  const { typesCache, createSubscription } = useSubscriptions();
 | 
			
		||||
  const { handleSubmit, errors, register } = useForm();
 | 
			
		||||
  const { handleSubmit, errors, register } = useForm({});
 | 
			
		||||
  const [radioState, setRadioState] = useState("ethereum_blockchain");
 | 
			
		||||
  let { getRootProps, getRadioProps } = useRadioGroup({
 | 
			
		||||
    name: "type",
 | 
			
		||||
| 
						 | 
				
			
			@ -41,10 +45,15 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
 | 
			
		|||
  const createSubscriptionWrap = (props) => {
 | 
			
		||||
    createSubscription.mutate({
 | 
			
		||||
      ...props,
 | 
			
		||||
      color: color,
 | 
			
		||||
      type: isFreeOption ? "free" : radioState,
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const handleChangeColorComplete = (color) => {
 | 
			
		||||
    setColor(color.hex);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <form onSubmit={handleSubmit(createSubscriptionWrap)}>
 | 
			
		||||
      <ModalHeader>Subscribe to a new address</ModalHeader>
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +92,7 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
 | 
			
		|||
              : `On which source?`}
 | 
			
		||||
          </Text>
 | 
			
		||||
 | 
			
		||||
          <FormControl isInvalid={errors.type}>
 | 
			
		||||
          <FormControl isInvalid={errors.subscription_type}>
 | 
			
		||||
            <HStack {...group} alignItems="stretch">
 | 
			
		||||
              {typesCache.data.subscriptions.map((type) => {
 | 
			
		||||
                const radio = getRadioProps({
 | 
			
		||||
| 
						 | 
				
			
			@ -100,9 +109,54 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
 | 
			
		|||
                );
 | 
			
		||||
              })}
 | 
			
		||||
            </HStack>
 | 
			
		||||
            <Input
 | 
			
		||||
              type="hidden"
 | 
			
		||||
              placeholder="subscription_type"
 | 
			
		||||
              name="subscription_type"
 | 
			
		||||
              ref={register({ required: "select type" })}
 | 
			
		||||
              value={radioState}
 | 
			
		||||
              onChange={() => null}
 | 
			
		||||
            ></Input>
 | 
			
		||||
            <FormErrorMessage color="unsafe.400" pl="1">
 | 
			
		||||
              {errors.subscription_type_ && errors.subscription_type_.message}
 | 
			
		||||
            </FormErrorMessage>
 | 
			
		||||
          </FormControl>
 | 
			
		||||
        </Stack>
 | 
			
		||||
        <Input placeholder="color" name="color" ref={register()}></Input>
 | 
			
		||||
        <FormControl isInvalid={errors.color}>
 | 
			
		||||
          <Stack direction="row" pb={2}>
 | 
			
		||||
            <Text fontWeight="600" alignSelf="center">
 | 
			
		||||
              Label color
 | 
			
		||||
            </Text>{" "}
 | 
			
		||||
            <IconButton
 | 
			
		||||
              size="md"
 | 
			
		||||
              // colorScheme="primary"
 | 
			
		||||
              color={"white.100"}
 | 
			
		||||
              _hover={{ bgColor: { color } }}
 | 
			
		||||
              bgColor={color}
 | 
			
		||||
              variant="outline"
 | 
			
		||||
              onClick={() => setColor(makeColor())}
 | 
			
		||||
              icon={<BiRefresh />}
 | 
			
		||||
            />
 | 
			
		||||
            <Input
 | 
			
		||||
              type="input"
 | 
			
		||||
              placeholder="color"
 | 
			
		||||
              name="color"
 | 
			
		||||
              ref={register({ required: "color is required!" })}
 | 
			
		||||
              value={color}
 | 
			
		||||
              onChange={() => null}
 | 
			
		||||
              w="200px"
 | 
			
		||||
            ></Input>
 | 
			
		||||
          </Stack>
 | 
			
		||||
 | 
			
		||||
          <GithubPicker
 | 
			
		||||
            // color={this.state.background}
 | 
			
		||||
            onChangeComplete={handleChangeColorComplete}
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <FormErrorMessage color="unsafe.400" pl="1">
 | 
			
		||||
            {errors.color && errors.color.message}
 | 
			
		||||
          </FormErrorMessage>
 | 
			
		||||
        </FormControl>
 | 
			
		||||
      </ModalBody>
 | 
			
		||||
      <ModalFooter>
 | 
			
		||||
        <Button
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +166,9 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
 | 
			
		|||
        >
 | 
			
		||||
          Confirm
 | 
			
		||||
        </Button>
 | 
			
		||||
        <Button colorScheme="gray">Cancel</Button>
 | 
			
		||||
        <Button colorScheme="gray" onClick={onClose}>
 | 
			
		||||
          Cancel
 | 
			
		||||
        </Button>
 | 
			
		||||
      </ModalFooter>
 | 
			
		||||
    </form>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,13 +17,17 @@ import moment from "moment";
 | 
			
		|||
import CopyButton from "./CopyButton";
 | 
			
		||||
import { useSubscriptions } from "../core/hooks";
 | 
			
		||||
import ConfirmationRequest from "./ConfirmationRequest";
 | 
			
		||||
import ColorSelector from "./ColorSelector";
 | 
			
		||||
 | 
			
		||||
const SubscriptionsList = () => {
 | 
			
		||||
  const { subscriptionsCache, changeNote, deleteSubscription } =
 | 
			
		||||
  const { subscriptionsCache, updateSubscription, deleteSubscription } =
 | 
			
		||||
    useSubscriptions();
 | 
			
		||||
 | 
			
		||||
  const updateCallback = ({ id, note }) => {
 | 
			
		||||
    changeNote.mutate({ id, note });
 | 
			
		||||
  const updateCallback = ({ id, label, color }) => {
 | 
			
		||||
    const data = { id: id };
 | 
			
		||||
    label && (data.label = label);
 | 
			
		||||
    color && (data.color = color);
 | 
			
		||||
    updateSubscription.mutate(data);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (subscriptionsCache.data) {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +49,7 @@ const SubscriptionsList = () => {
 | 
			
		|||
            <Th>Token</Th>
 | 
			
		||||
            <Th>Label</Th>
 | 
			
		||||
            <Th>Address</Th>
 | 
			
		||||
            <Th>Color</Th>
 | 
			
		||||
            <Th>Date Created</Th>
 | 
			
		||||
            <Th>Actions</Th>
 | 
			
		||||
          </Tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +104,15 @@ const SubscriptionsList = () => {
 | 
			
		|||
                <Td mr={4} p={0}>
 | 
			
		||||
                  <CopyButton>{subscription.address}</CopyButton>
 | 
			
		||||
                </Td>
 | 
			
		||||
                <Td>
 | 
			
		||||
                  <ColorSelector
 | 
			
		||||
                    // subscriptionId={subscription.id}
 | 
			
		||||
                    initialColor={subscription.color}
 | 
			
		||||
                    callback={(color) =>
 | 
			
		||||
                      updateCallback({ id: subscription.id, color: color })
 | 
			
		||||
                    }
 | 
			
		||||
                  />
 | 
			
		||||
                </Td>
 | 
			
		||||
                <Td py={0}>{moment(subscription.created_at).format("L")}</Td>
 | 
			
		||||
 | 
			
		||||
                <Td py={0}>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,12 +50,15 @@ const useSubscriptions = () => {
 | 
			
		|||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const changeNote = useMutation(SubscriptionsService.modifySubscription(), {
 | 
			
		||||
    onError: (error) => toast(error, "error"),
 | 
			
		||||
    onSuccess: () => {
 | 
			
		||||
      subscriptionsCache.refetch();
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
  const updateSubscription = useMutation(
 | 
			
		||||
    SubscriptionsService.modifySubscription(),
 | 
			
		||||
    {
 | 
			
		||||
      onError: (error) => toast(error, "error"),
 | 
			
		||||
      onSuccess: () => {
 | 
			
		||||
        subscriptionsCache.refetch();
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const deleteSubscription = useMutation(
 | 
			
		||||
    SubscriptionsService.deleteSubscription(),
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +74,7 @@ const useSubscriptions = () => {
 | 
			
		|||
    createSubscription,
 | 
			
		||||
    subscriptionsCache,
 | 
			
		||||
    typesCache,
 | 
			
		||||
    changeNote,
 | 
			
		||||
    updateSubscription,
 | 
			
		||||
    deleteSubscription,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,9 +62,10 @@ export const createSubscription =
 | 
			
		|||
 | 
			
		||||
export const modifySubscription =
 | 
			
		||||
  () =>
 | 
			
		||||
  ({ id, note }) => {
 | 
			
		||||
  ({ id, label, color }) => {
 | 
			
		||||
    const data = new FormData();
 | 
			
		||||
    data.append("note", note);
 | 
			
		||||
    color && data.append("color", color);
 | 
			
		||||
    label && data.append("label", label);
 | 
			
		||||
    data.append("id", id);
 | 
			
		||||
    return http({
 | 
			
		||||
      method: "POST",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
export const makeColor = () => {
 | 
			
		||||
  var result = "#";
 | 
			
		||||
  var characters = "0123456789ABCDEF";
 | 
			
		||||
  var charactersLength = characters.length;
 | 
			
		||||
  for (var i = 0; i < 6; i++) {
 | 
			
		||||
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
};
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue