react-icons/fi#FiSettings TypeScript Examples

The following examples show how to use react-icons/fi#FiSettings. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Navigation.tsx    From bluebubbles-server with Apache License 2.0 6 votes vote down vote up
LinkItems: Array<LinkItemProps> = [
    { name: 'Home', icon: FiHome, to: '/' },
    { name: 'Devices', icon: FiMonitor, to: '/devices' },
    { name: 'Contacts', icon: BsPersonCircle, to: '/contacts' },
    { name: 'Debug & Logs', icon: AiOutlineBug, to: '/logs' },
    { name: 'Google FCM', icon: BiNotification, to: '/fcm' },
    { name: 'API & Webhooks', icon: AiOutlineApi, to: '/webhooks' },
    { name: 'Guides & Links', icon: BsBook, to: '/guides' },
    { name: 'Settings', icon: FiSettings, to: '/settings' }
]
Example #2
Source File: DmChat.tsx    From meshtastic-web with GNU General Public License v3.0 6 votes vote down vote up
DmChat = ({
  node,
  selectedIndex,
  setSelectedIndex,
}: DmChatProps): JSX.Element => {
  return (
    <SidebarItem
      key={node.num}
      selected={node.num === selectedIndex}
      setSelected={(): void => {
        setSelectedIndex(node.num);
      }}
      actions={<IconButton nested icon={<FiSettings />} />}
    >
      <div className="flex dark:text-white">
        <div className="m-auto">
          <Hashicon value={node.num.toString()} size={32} />
        </div>
      </div>
      <div className="my-auto mr-auto font-semibold dark:text-white">
        {node.user?.longName ?? 'Unknown'}
      </div>
    </SidebarItem>
  );
}
Example #3
Source File: index.tsx    From meshtastic-web with GNU General Public License v3.0 5 votes vote down vote up
Layout = ({
  title,
  icon,
  sidebarContents,
  children,
}: LayoutProps): JSX.Element => {
  const [settingsOpen, setSettingsOpen] = useState(false);

  const route = useRoute();

  const tabs: Omit<TabProps, 'activeLeft' | 'activeRight'>[] = [
    {
      title: 'Messages',
      icon: <FiMessageCircle />,
      link: routes.messages().link,
      active: route.name === 'messages',
    },
    {
      title: 'Map',
      icon: <RiRoadMapLine />,
      link: routes.map().link,
      active: route.name === 'map',
    },
    {
      title: 'Extensions',
      icon: <VscExtensions />,
      link: routes.extensions().link,
      active: route.name === 'extensions',
    },
  ];

  return (
    <div className="relative flex w-full overflow-hidden bg-white dark:bg-secondaryDark">
      <div className="flex flex-grow">
        <Sidebar settingsOpen={settingsOpen} setSettingsOpen={setSettingsOpen}>
          <div className="bg-white px-1 pt-1 drop-shadow-md dark:bg-primaryDark">
            <div className="flex h-10 gap-1">
              <div className="my-auto">
                <IconButton icon={icon} />
              </div>
              <div className="my-auto text-lg font-medium dark:text-white">
                {title}
              </div>
            </div>
          </div>
          <div className="flex flex-col gap-2">{sidebarContents}</div>
        </Sidebar>
      </div>
      <ErrorBoundary FallbackComponent={ErrorFallback}>
        <div className="flex h-full w-full flex-col bg-gray-300 dark:bg-secondaryDark">
          <div className="flex w-full bg-white pt-1 dark:bg-primaryDark">
            <div className="z-10 -mr-2 h-8">
              <IconButton
                className="m-1"
                icon={<FiSettings />}
                onClick={(): void => {
                  setSettingsOpen(!settingsOpen);
                }}
                active={settingsOpen}
              />
            </div>
            <Tabs tabs={tabs} />
          </div>
          <div className="flex flex-grow">{children}</div>
        </div>
      </ErrorBoundary>
    </div>
  );
}
Example #4
Source File: index.tsx    From dxvote with GNU Affero General Public License v3.0 4 votes vote down vote up
Header = observer(() => {
  const NavItem = withRouter(
    ({ route, history, children }: NavItemProps & RouteComponentProps) => {
      return (
        <div
          style={{ cursor: 'pointer' }}
          onClick={() => {
            history.push(route);
          }}
        >
          {' '}
          {children}{' '}
        </div>
      );
    }
  );

  const {
    context: { providerStore, blockchainStore, configStore, daoStore },
  } = useContext();

  const { active, account } = providerStore.getActiveWeb3React();

  const isTestingEnv = !window?.location?.href?.includes('dxvote.eth');

  const networkName = configStore.getActiveChainName();

  const { userRep, totalSupply } =
    active && blockchainStore.initialLoadComplete
      ? daoStore.getRepAt(account, providerStore.getCurrentBlockNumber())
      : { userRep: bnum(0), totalSupply: bnum(0) };
  const repPercentage = active
    ? userRep.times(100).div(totalSupply).toFixed(4)
    : bnum(0);

  // const votingMachines = configStore.getNetworkContracts().votingMachines;
  // const votingMachineTokens = _.uniq(
  //   Object.keys(votingMachines).map((votingMachineAddress, i) =>
  //     configStore
  //       .getTokensOfNetwork()
  //       .find(
  //         token => token.address === votingMachines[votingMachineAddress].token
  //       )
  //   )
  // );

  return (
    <NavWrapper>
      <NavSection>
        <NavItem route={`/${networkName}/proposals`}>
          <MenuItem>
            <img alt="dxdao" src={dxdaoIcon} />
            {isTestingEnv && <WarningDev>Testing Environment</WarningDev>}
          </MenuItem>
        </NavItem>
      </NavSection>
      {!active ? (
        <NavSection>
          <Web3ConnectStatus text="Connect Wallet" />
          <NavItem route={`/config`}>
            <a>
              <FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
            </a>
          </NavItem>
        </NavSection>
      ) : blockchainStore.initialLoadComplete ? (
        <NavSection>
          {account && active && (
            <>
              {/* {useBalances(
                account
                  ? votingMachineTokens.map(votingMachineToken => ({
                      assetAddress: votingMachineToken.address,
                      fromAddress: account,
                    }))
                  : []
              ).map((votingMachineTokenBalance, i) => {
                return (
                  <ItemBox key={i}>
                    {formatCurrency(
                      normalizeBalance(votingMachineTokenBalance)
                    )}{' '}
                    {votingMachineTokens[i].symbol}{' '}
                  </ItemBox>
                );
              })} */}
              {repPercentage.toString() !== 'NaN' && (
                <ItemBox> {repPercentage.toString()} % REP </ItemBox>
              )}
            </>
          )}
          <Web3ConnectStatus text="Connect Wallet" />
          <NavItem route={`/${networkName}/info`}>
            <a>
              <FiBarChart2 style={{ margin: '0px 10px', color: '#616161' }} />
            </a>
          </NavItem>
          <NavItem route={`/config`}>
            <a>
              <FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
            </a>
          </NavItem>
          {account && (
            <NavItem route={`/${networkName}/user/${account}`}>
              <a>
                <FiUser style={{ margin: '0px 10px', color: '#616161' }} />
              </a>
            </NavItem>
          )}
        </NavSection>
      ) : (
        <NavSection>
          <Web3ConnectStatus text="Connect Wallet" />
          <NavItem route={`/config`}>
            <a>
              <FiSettings style={{ margin: '0px 10px', color: '#616161' }} />
            </a>
          </NavItem>
        </NavSection>
      )}
    </NavWrapper>
  );
})
Example #5
Source File: GitHubSiteLayout.tsx    From pagely with MIT License 4 votes vote down vote up
SidebarLayout: React.FC<{
  activeTab: 'code' | 'setup' | 'settings';
  title?: string;
}> = ({ activeTab, title, ...props }) => {
  const { emailAddresses, profileImageUrl, fullName, firstName } = useUser();
  const { signOut } = useClerk();

  const router = useRouter();
  const { data } = useClerkSWR<ghSites>(
    `/api/getSiteData/github/?siteId=${router.query.siteId}`
  );
  return (
    <div>
      <div className='block lg:hidden'>
        <DashboardNav />
        <Head>
          <title>
            {title ||
              data?.siteName +
                ' - ' +
                activeTab.charAt(0).toUpperCase() +
                activeTab.slice(1) +
                ' | ' +
                'Pagely'}
          </title>
        </Head>
      </div>
      <div className='lg:flex'>
        {/* <div className='sticky top-0 overflow-y-hidden'> */}
        <div
          style={{ position: 'sticky' }}
          className='absolute top-0 h-screen left-0 px-10 py-5 bg-gray-50 w-[20vw] border-r hidden flex-col justify-between lg:flex'>
          <div>
            <Link href='/dashboard'>
              <a>
                <small className='text-gray-700 hover:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                  {' '}
                  {'<'}- Go back
                </small>
              </a>
            </Link>
            <ul className='mt-10'>
              <li
                className={`my-2 rounded ${
                  activeTab === 'setup' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={`/github-site/${data?.id}`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <GoInbox className='relative inline-block bottom-[2px]' />{' '}
                    Setup
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'code' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={`/github-site/${data?.id}/code`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <BiCode className='relative inline-block bottom-[2px]' />{' '}
                    Code injection
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'settings'
                    ? ' bg-gray-200'
                    : ' hover:bg-gray-300'
                }`}>
                <Link href={`/github-site/${data?.id}/settings`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <FiSettings className='relative inline-block bottom-[2px]' />{' '}
                    Settings
                  </a>
                </Link>
              </li>
            </ul>
          </div>
          <ProfileDropdown
            emailAddresses={emailAddresses}
            profileImageUrl={profileImageUrl}
            fullName={fullName}
            firstName={firstName}
            signOut={signOut}
          />
        </div>
        <div className='mx-10 mt-20'>{props.children}</div>
      </div>
      <Toaster />
    </div>
  );
}
Example #6
Source File: SidebarLayout.tsx    From pagely with MIT License 4 votes vote down vote up
SidebarLayout: React.FC<{
  activeTab: 'code' | 'setup' | 'pages' | 'settings' | 'seo';
  title?: string;
}> = ({ activeTab, title, ...props }) => {
  const { emailAddresses, profileImageUrl, fullName, firstName } = useUser();
  const { signOut } = useClerk();

  const router = useRouter();
  const { data } = useClerkSWR<notionSites>(
    `/api/getSiteData/notion/?siteId=${router.query.notionId}`
  );
  return (
    <div>
      <div className='block lg:hidden'>
        <DashboardNav />
        <Head>
          <title>
            {title ||
              data?.siteName +
                ' - ' +
                activeTab.charAt(0).toUpperCase() +
                activeTab.slice(1) +
                ' | ' +
                'Pagely'}
          </title>
        </Head>
      </div>
      <div className='lg:flex'>
        {/* <div className='sticky top-0 overflow-y-hidden'> */}
        <div
          style={{ position: 'sticky' }}
          className='absolute top-0 h-screen left-0 px-10 py-5 bg-gray-50 w-[20vw] border-r hidden flex-col justify-between lg:flex'>
          <div>
            <Link href='/dashboard'>
              <a>
                <small className='text-gray-700 hover:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                  {' '}
                  {'<'}- Go back
                </small>
              </a>
            </Link>
            <ul className='mt-10'>
              <li
                className={`my-2 rounded ${
                  activeTab === 'setup' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={'/notion-site/' + data?.id}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <GoInbox className='relative inline-block bottom-[2px]' />{' '}
                    Setup
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'seo' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={`/notion-site/${data?.id}/seo`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <BiSearchAlt className='relative inline-block bottom-[2px]' />{' '}
                    SEO
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'code' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={`/notion-site/${data?.id}/code`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <BiCode className='relative inline-block bottom-[2px]' />{' '}
                    Code injection
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'pages' ? ' bg-gray-200' : ' hover:bg-gray-300'
                }`}>
                <Link href={`/notion-site/${data?.id}/pages`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <HiOutlineNewspaper className='relative inline-block bottom-[2px]' />{' '}
                    Pages
                  </a>
                </Link>
              </li>
              <li
                className={`my-2 rounded ${
                  activeTab === 'settings'
                    ? ' bg-gray-200'
                    : ' hover:bg-gray-300'
                }`}>
                <Link href={`/notion-site/${data?.id}/settings`}>
                  <a className='block px-3 py-2 my-2 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-700'>
                    {' '}
                    <FiSettings className='relative inline-block bottom-[2px]' />{' '}
                    Settings
                  </a>
                </Link>
              </li>
            </ul>
          </div>
          <ProfileDropdown
            emailAddresses={emailAddresses}
            profileImageUrl={profileImageUrl}
            fullName={fullName}
            firstName={firstName}
            signOut={signOut}
          />
        </div>
        <div className='mx-10 mt-20'>{props.children}</div>
      </div>
      <Toaster />
    </div>
  );
}
Example #7
Source File: index.tsx    From jsonschema-editor-react with Apache License 2.0 4 votes vote down vote up
SchemaArray: React.FunctionComponent<SchemaArrayProps> = (
	props: React.PropsWithChildren<SchemaArrayProps>
) => {
	const { schemaState, isReadOnly } = props;

	const state = useState(schemaState.items as JSONSchema7);
	const isReadOnlyState = useState(isReadOnly);

	const { length } = state.path.filter((name) => name !== "properties");
	const tagPaddingLeftStyle = {
		paddingLeft: `${20 * (length + 1)}px`,
	};

	const onCloseAdvanced = (): void => {
		localState.isAdvancedOpen.set(false);
	};

	const showadvanced = (): void => {
		localState.isAdvancedOpen.set(true);
	};

	const focusRef = React.createRef<HTMLElement>();

	const localState = useState({
		isAdvancedOpen: false,
	});

	return (
		<>
			<Flex
				direction="row"
				wrap="nowrap"
				className="array-item"
				mt={2}
				mr={5}
				style={tagPaddingLeftStyle}
			>
				<Input
					key="Items"
					isDisabled
					value="Items"
					size="sm"
					flexShrink={1}
					margin={2}
					variant="outline"
				/>
				<Checkbox isDisabled margin={2} colorScheme="blue" />
				<Select
					variant="outline"
					isDisabled={isReadOnlyState.value}
					value={state.type.value as JSONSchema7TypeName}
					size="sm"
					margin={2}
					placeholder="Choose data type"
					onChange={(evt: React.ChangeEvent<HTMLSelectElement>) => {
						const newSchema = handleTypeChange(
							evt.target.value as JSONSchema7TypeName,
							false
						);
						state.set(newSchema as JSONSchema7);
					}}
				>
					{SchemaTypes.map((item, index) => {
						return (
							<option key={String(index)} value={item}>
								{item}
							</option>
						);
					})}
				</Select>
				<Input
					value={state.title.value}
					isDisabled={isReadOnlyState.value}
					size="sm"
					margin={2}
					variant="outline"
					placeholder="Add Title"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						state.title.set(evt.target.value);
					}}
				/>
				<Input
					value={state.description.value}
					isDisabled={isReadOnlyState.value}
					size="sm"
					margin={2}
					variant="outline"
					placeholder="Add Description"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						state.description.set(evt.target.value);
					}}
				/>
				<Tooltip
					hasArrow
					aria-label="Advanced Settings"
					label="Advanced Settings"
					placement="top"
				>
					<IconButton
						isRound
						isDisabled={isReadOnlyState.value}
						size="sm"
						mt={2}
						mb={2}
						ml={1}
						variant="link"
						colorScheme="blue"
						fontSize="16px"
						icon={<FiSettings />}
						aria-label="Advanced Settings"
						onClick={() => {
							showadvanced();
						}}
					/>
				</Tooltip>

				{state.type.value === "object" && (
					<Tooltip
						hasArrow
						aria-label="Add Child Node"
						label="Add Child Node"
						placement="top"
					>
						<IconButton
							isRound
							isDisabled={isReadOnlyState.value}
							size="sm"
							mt={2}
							mb={2}
							mr={2}
							variant="link"
							colorScheme="green"
							fontSize="16px"
							icon={<IoIosAddCircleOutline />}
							aria-label="Add Child Node"
							onClick={() => {
								const fieldName = `field_${random()}`;
								(state.properties as State<{
									[key: string]: JSONSchema7;
								}>)[fieldName].set(getDefaultSchema(DataType.string));
							}}
						/>
					</Tooltip>
				)}
			</Flex>
			{state.type?.value === "object" && (
				<SchemaObject isReadOnly={isReadOnlyState} schemaState={state} />
			)}
			{state.type?.value === "array" && (
				<SchemaArray isReadOnly={isReadOnlyState} schemaState={state} />
			)}
			<Modal
				isOpen={localState.isAdvancedOpen.get()}
				finalFocusRef={focusRef}
				size="lg"
				onClose={onCloseAdvanced}
			>
				<ModalOverlay />
				<ModalContent>
					<ModalHeader textAlign="center">Advanced Schema Settings</ModalHeader>

					<ModalBody>
						<AdvancedSettings itemStateProp={state} />
					</ModalBody>

					<ModalFooter>
						<Button
							colorScheme="blue"
							variant="ghost"
							mr={3}
							onClick={onCloseAdvanced}
						>
							Close
						</Button>
					</ModalFooter>
				</ModalContent>
			</Modal>
		</>
	);
}
Example #8
Source File: index.tsx    From jsonschema-editor-react with Apache License 2.0 4 votes vote down vote up
SchemaItem: React.FunctionComponent<SchemaItemProps> = (
	props: React.PropsWithChildren<SchemaItemProps>
) => {
	const {
		name,
		itemStateProp,
		showadvanced,
		required,
		parentStateProp,
		isReadOnly,
	} = props;

	// const itemState = useState(itemStateProp);
	const parentState = useState(parentStateProp);
	const parentStateOrNull: State<JSONSchema7> | undefined = parentState.ornull;
	const propertiesOrNull:
		| State<{
				[key: string]: JSONSchema7Definition;
		  }>
		| undefined = parentStateOrNull.properties.ornull;

	const nameState = useState(name);
	const isReadOnlyState = useState(isReadOnly);

	const itemState = useState(
		(parentStateProp.properties as State<{
			[key: string]: JSONSchema7;
		}>).nested(nameState.value)
	);

	const { length } = parentState.path.filter((name) => name !== "properties");
	const tagPaddingLeftStyle = {
		paddingLeft: `${20 * (length + 1)}px`,
	};

	const isRequired = required
		? required.length > 0 && required.includes(name)
		: false;
	const toast = useToast();

	// Debounce callback
	const debounced = useDebouncedCallback(
		// function
		(newValue: string) => {
			// Todo: make toast for duplicate properties
			if (propertiesOrNull && propertiesOrNull[newValue].value) {
				toast({
					title: "Duplicate Property",
					description: "Property already exists!",
					status: "error",
					duration: 1000,
					isClosable: true,
					position: "top",
				});
			} else {
				const oldName = name;
				const proptoupdate = newValue;

				const newobj = renameKeys(
					{ [oldName]: proptoupdate },
					parentState.properties.value
				);
				parentStateOrNull.properties.set(JSON.parse(JSON.stringify(newobj)));
			}
		},
		// delay in ms
		1000
	);

	if (!itemState.value) {
		return <></>;
	}

	return (
		<div>
			<Flex
				alignContent="space-evenly"
				direction="row"
				wrap="nowrap"
				className="schema-item"
				style={tagPaddingLeftStyle}
			>
				<Input
					isDisabled={isReadOnlyState.value}
					defaultValue={nameState.value}
					size="sm"
					margin={2}
					variant="outline"
					placeholder="Enter property name"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						debounced(evt.target.value);
					}}
				/>
				<Checkbox
					isDisabled={isReadOnlyState.value}
					isChecked={isRequired}
					margin={2}
					colorScheme="blue"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						if (!evt.target.checked && required.includes(name)) {
							(parentState.required as State<string[]>)[
								required.indexOf(name)
							].set(none);
						} else {
							parentState.required.merge([name]);
						}
					}}
				/>
				<Select
					isDisabled={false}
					variant="outline"
					value={itemState.type.value}
					size="sm"
					margin={2}
					placeholder="Choose data type"
					onChange={(evt: React.ChangeEvent<HTMLSelectElement>) => {
						const newSchema = handleTypeChange(
							evt.target.value as JSONSchema7TypeName,
							false
						);
						itemState.set(newSchema as JSONSchema7);
					}}
				>
					{SchemaTypes.map((item, index) => {
						return (
							<option key={String(index)} value={item}>
								{item}
							</option>
						);
					})}
				</Select>
				<Input
					isDisabled={isReadOnlyState.value}
					value={itemState.title.value || ""}
					size="sm"
					margin={2}
					variant="outline"
					placeholder="Add Title"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						itemState.title.set(evt.target.value);
					}}
				/>
				<Input
					isDisabled={isReadOnlyState.value}
					value={itemState.description.value || ""}
					size="sm"
					margin={2}
					variant="outline"
					placeholder="Add Description"
					onChange={(evt: React.ChangeEvent<HTMLInputElement>) => {
						itemState.description.set(evt.target.value);
					}}
				/>

				{itemState.type.value !== "object" && itemState.type.value !== "array" && (
					<Tooltip
						hasArrow
						aria-label="Advanced Settings"
						label="Advanced Settings"
						placement="top"
					>
						<IconButton
							isRound
							isDisabled={isReadOnlyState.value}
							size="sm"
							mt={2}
							mb={2}
							ml={1}
							variant="link"
							colorScheme="blue"
							fontSize="16px"
							icon={<FiSettings />}
							aria-label="Advanced Settings"
							onClick={() => {
								showadvanced(name);
							}}
						/>
					</Tooltip>
				)}

				<Tooltip
					hasArrow
					aria-label="Remove Node"
					label="Remove Node"
					placement="top"
				>
					<IconButton
						isRound
						isDisabled={isReadOnlyState.value}
						size="sm"
						mt={2}
						mb={2}
						ml={1}
						variant="link"
						colorScheme="red"
						fontSize="16px"
						icon={<AiOutlineDelete />}
						aria-label="Remove Node"
						onClick={() => {
							const updatedState = deleteKey(
								nameState.value,
								JSON.parse(JSON.stringify(parentState.properties.value))
							);
							parentState.properties.set(updatedState);
						}}
					/>
				</Tooltip>

				{itemState.type?.value === "object" ? (
					<DropPlus
						isDisabled={isReadOnlyState.value}
						parentStateProp={parentState}
						itemStateProp={itemStateProp}
					/>
				) : (
					<Tooltip
						hasArrow
						aria-label="Add Sibling Node"
						label="Add Sibling Node"
						placement="top"
					>
						<IconButton
							isRound
							isDisabled={isReadOnlyState.value}
							size="sm"
							mt={2}
							mb={2}
							mr={2}
							variant="link"
							colorScheme="green"
							fontSize="16px"
							icon={<IoIosAddCircleOutline />}
							aria-label="Add Sibling Node"
							onClick={() => {
								if (propertiesOrNull) {
									const fieldName = `field_${random()}`;
									propertiesOrNull
										?.nested(fieldName)
										.set(getDefaultSchema(DataType.string) as JSONSchema7);
								}
							}}
						/>
					</Tooltip>
				)}
			</Flex>
			{itemState.type?.value === "object" && (
				<SchemaObject isReadOnly={isReadOnlyState} schemaState={itemState} />
			)}
			{itemState.type?.value === "array" && (
				<SchemaArray isReadOnly={isReadOnlyState} schemaState={itemState} />
			)}
		</div>
	);
}
Example #9
Source File: Settings.tsx    From Twenty48 with GNU General Public License v3.0 4 votes vote down vote up
Settings: React.FC = () => {
  const version = packJson['version']
  const [theme, setTheme] = useRecoilState<ThemeType>(ThemeState)
  const [anchorEl, setAnchorEl] = useState<Element | null | undefined>(null)

  const [isCacheClear, setIsCacheClear] = useState(() => {
    if (
      localStorage.getItem(BESTSCORE) ||
      localStorage.getItem(GAMESTATE) ||
      localStorage.getItem(THEME)
    ) {
      return false
    }
    return true
  })
  const cacheClearText = isCacheClear ? 'Cache is Clear' : 'Clear Cache'

  useEffect(() => {
    localStorage.setItem(THEME, theme)
  }, [theme])

  const removeLocalStorage = (): void => {
    localStorage.removeItem(THEME)
    localStorage.removeItem(GAMESTATE)
    localStorage.removeItem(BESTSCORE)
    setIsCacheClear(true)
  }

  const setSelectedTheme = (
    e: React.ChangeEvent<{ name?: string; value: unknown }>,
  ): void => {
    setTheme(e.target.value as ThemeType)
  }

  const getPopoverBody = (): React.ReactElement => {
    return (
      <div className={`popover-body popover-body-${theme}`}>
        <div className="settings-item center">
          <h3 onClick={removeLocalStorage}>{cacheClearText}</h3>
        </div>
        <Divider />
        <div className="settings-item">
          <h3>Theme:</h3>
          <div className="center-item">
            {theme === ThemeType.DARK ? (
              <GiMoonBats size="22px" className="theme-icon" />
            ) : (
              <GiUbisoftSun size="22px" className="theme-icon" />
            )}
            <FormControl className="no-decoration">
              <NativeSelect
                value={theme}
                className={`select-${theme}`}
                onChange={setSelectedTheme}
              >
                {Object.values(ThemeType).map((type, idx) => {
                  return (
                    <option key={idx} value={type}>
                      {type}
                    </option>
                  )
                })}
              </NativeSelect>
            </FormControl>
          </div>
        </div>
        <Divider />
        <div className="settings-item">
          <h3>Version:</h3>
          <h4 className="center-item">{version}</h4>
        </div>
        <Divider />
        <div className="settings-item ">
          <h3>Made with:</h3>
          <img src={logo} className="react-icon" />
        </div>
      </div>
    )
  }

  return (
    <>
      <div>
        <FiSettings
          id="settings-cog"
          className="settings-cog"
          size="30px"
          onClick={(e): void => setAnchorEl(e.currentTarget)}
        />
      </div>

      {/* Popover component: hidden until above button click */}
      <Popover
        open={anchorEl !== null}
        anchorEl={anchorEl}
        onClose={(): void => setAnchorEl(null)}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
      >
        {getPopoverBody()}
      </Popover>
    </>
  )
}
Example #10
Source File: ChannelChat.tsx    From meshtastic-web with GNU General Public License v3.0 4 votes vote down vote up
ChannelChat = ({
  channel,
  selectedIndex,
  setSelectedIndex,
}: ChannelChatProps): JSX.Element => {
  const myNodeNum = useAppSelector(
    (state) => state.meshtastic.radio.hardware,
  ).myNodeNum;
  const nodes = useAppSelector((state) => state.meshtastic.nodes).filter(
    (node) => node.data.num !== myNodeNum,
  );
  const chats = useAppSelector((state) => state.meshtastic.chats);
  const channels = useAppSelector(
    (state) => state.meshtastic.radio.channels,
  ).filter((ch) => ch.role !== Protobuf.Channel_Role.DISABLED);

  return (
    <SidebarItem
      key={channel.index}
      selected={channel.index === selectedIndex}
      setSelected={(): void => {
        setSelectedIndex(channel.index);
      }}
      actions={<IconButton nested icon={<FiSettings />} />}
    >
      <Tooltip
        content={
          channel.settings?.name.length
            ? channel.settings.name
            : `CH: ${channel.index}`
        }
      >
        <div className="flex h-8 w-8 rounded-full bg-gray-300 dark:bg-primaryDark dark:text-white">
          <div className="m-auto">
            {channel.role === Protobuf.Channel_Role.PRIMARY ? (
              <MdPublic />
            ) : (
              <p>
                {channel.settings?.name.length
                  ? channel.settings.name.substring(0, 3).toUpperCase()
                  : `CH: ${channel.index}`}
              </p>
            )}
          </div>
        </div>
      </Tooltip>
      {chats[channel.index]?.messages.length ? (
        <>
          <div className="mx-2 flex h-8">
            {[
              ...new Set(
                chats[channel.index]?.messages.flatMap(({ message }) => [
                  message.packet.from,
                ]),
              ),
            ]
              .sort()
              .map((nodeId) => {
                return (
                  <Tooltip
                    key={nodeId}
                    content={
                      nodes.find((node) => node.data.num === nodeId)?.data.user
                        ?.longName ?? 'UNK'
                    }
                  >
                    <div className="flex h-full">
                      <m.div
                        whileHover={{ scale: 1.1 }}
                        className="my-auto -ml-2"
                      >
                        <Hashicon value={nodeId.toString()} size={20} />
                      </m.div>
                    </div>
                  </Tooltip>
                );
              })}
          </div>
          <div className="my-auto ml-auto text-xs font-semibold dark:text-gray-400">
            {chats[channel.index].messages.length ? (
              <TimeAgo datetime={chats[channel.index].lastInterraction} />
            ) : (
              <div>No messages</div>
            )}
          </div>
        </>
      ) : (
        <div className="my-auto dark:text-white">No messages</div>
      )}
    </SidebarItem>
  );
}