gatsby#navigate TypeScript Examples

The following examples show how to use gatsby#navigate. 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: index.tsx    From admin with MIT License 6 votes vote down vote up
Table.Cell = React.forwardRef<HTMLTableCellElement, TableCellProps>(
  ({ className, linkTo, children, ...props }, ref) => (
    <td
      ref={ref}
      className={clsx("inter-small-regular h-[40px]", className)}
      {...props}
      {...(linkTo && {
        onClick: (e) => {
          navigate(linkTo)
          e.stopPropagation()
        },
      })}
    >
      {children}
    </td>
  )
)
Example #2
Source File: new_case_guide.tsx    From j3pz-web with MIT License 6 votes vote down vote up
newCase = () => {
        const { kungfu } = this.state;
        if (this.name === '') {
            this.name = `${kungfu}配装`;
        }
        CaseService.create(kungfu!, this.name).then((res) => {
            if (res) {
                navigate(`/app#${res.id}`);
            } else {
                this.onConfirm();
            }
        });
        gtag('event', 'case.new', { kungfu, platform: 'web_pc' });
    };
Example #3
Source File: LayoutInner.tsx    From mantine with MIT License 6 votes vote down vote up
function getActions(data: ReturnType<typeof getDocsData>): SpotlightAction[] {
  return data.reduce<SpotlightAction[]>((acc, part) => {
    if (!part || !Array.isArray(part.groups)) {
      return acc;
    }

    part.groups.forEach((group) => {
      if (group && Array.isArray(group.pages)) {
        acc.push(
          ...group.pages.map((item) => ({
            title: item.title,
            description: item.search || item.description,
            onTrigger: () => navigate(item.slug),
          }))
        );
      }
    });

    part.uncategorized
      .filter(
        (page) =>
          page.title.toLowerCase() !== 'getting started' &&
          !page.title.toLowerCase().includes('version')
      )
      .forEach((page) => {
        acc.push({
          title: page.title,
          description: page.search || page.description,
          onTrigger: () => navigate(page.slug),
        });
      });

    return acc;
  }, []);
}
Example #4
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
Breadcrumb: React.FC<BreadcrumbProps> = ({
  previousRoute = "/a/settings",
  previousBreadcrumb = "Settings",
  currentPage,
  className,
  ...props
}) => {
  return (
    <div
      className={clsx(
        "w-full flex items-center inter-small-semibold text-grey-50 mb-4",
        className
      )}
      {...props}
    >
      <span
        className="text-violet-60 cursor-pointer"
        onClick={() => navigate(previousRoute)}
      >
        {previousBreadcrumb}
      </span>
      <span className="mx-0.5">
        <ChevronRightIcon size={16} />
      </span>
      <span>{currentPage}</span>
    </div>
  )
}
Example #5
Source File: UserProvider.tsx    From Frontend with MIT License 6 votes vote down vote up
UserProvider: React.FC = ({ children }) => {
  const { userStore, locationStore } = useStores();
  const auth = useAuth();
  React.useEffect(() => {
    auth.getRedirectResult().then(
      () => {
        if (locationStore.next) {
          const { next } = locationStore;
          navigate(next);
        }
      },
      () => {
        debugger;
      }
    );

    const listener = auth.onAuthStateChanged((authUser) => {
      userStore.setAuthUser(authUser);
      auth.currentUser?.getIdToken().then((token) => {
        localStorage.setItem('token', token);
        userStore.setToken(token);
      });
    });
    return () => listener();
  }, []);
  return <>{children}</>;
}
Example #6
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
Table.Row = React.forwardRef<HTMLTableRowElement, TableRowProps>(
  ({ className, actions, children, linkTo, forceDropdown, ...props }, ref) => (
    <tr
      ref={ref}
      className={clsx(
        "inter-small-regular border-t border-b border-grey-20 text-grey-90",
        className,
        { "cursor-pointer hover:bg-grey-5": linkTo !== undefined }
      )}
      {...props}
      {...(linkTo && {
        onClick: () => {
          navigate(linkTo)
        },
      })}
    >
      {children}
      {actions && (
        <Table.Cell onClick={(e) => e.stopPropagation()} className="w-[32px]">
          <Actionables forceDropdown={forceDropdown} actions={actions} />
        </Table.Cell>
      )}
    </tr>
  )
)
Example #7
Source File: index.tsx    From website-docs with MIT License 6 votes vote down vote up
export function Layout({
  children,
  locale = [Locale.en, Locale.zh],
}: PropsWithChildren<Props>) {
  useEffect(() => {
    if (!window.DOCS_PINGCAP) {
      window.DOCS_PINGCAP = {
        globalHistory,
        navigate,
      }
    }
  }, [])

  return (
    <>
      <Navbar locale={locale} />
      <Section as="main">
        <Container>{children}</Container>
      </Section>
      <Footer />
    </>
  )
}
Example #8
Source File: commoncrewdata.tsx    From website with MIT License 6 votes vote down vote up
rankLinker = (roster: any, rank: number, symbol: string, column: string, direction: string, search: string) => {
	if (roster) return (<>{rank}</>);
	const linkState = {
		search: search ?? '',
		column: column,
		direction: direction ?? 'ascending',
		highlight: symbol ?? ''
	};
	const baseUrl = '/';
	let params = '';
	Object.entries(linkState).forEach(entry => {
		if (entry[1] !== '') {
			if (params !== '') params += '&';
			params += entry[0]+'='+encodeURI(entry[1]);
		}
	});
	const url = params !== '' ? baseUrl+'?'+params : baseUrl;
	return (
		<Link to={url} onClick={(event) => clickLink(event)}>{rank}</Link>
	);

	// On left clicks, use state instead of URL params because it's a little faster and cleaner
	function clickLink(e) {
		if (e.button === 0) {
			e.preventDefault();
			navigate(baseUrl, { state: linkState });
		}
	}
}
Example #9
Source File: portal.tsx    From midway with MIT License 6 votes vote down vote up
logout = (e: React.MouseEvent<HTMLAnchorElement>, updateCustomer: any) => {
  e.preventDefault()
  const customerToken = cookie.get('customer_token')
  fetch(`/.netlify/functions/logout`, {
    method: 'POST',
    body: JSON.stringify({
      accessToken: customerToken
    })
  })
  .then(() => {
    cookie.remove('customer_token')
    cookie.remove('customer_email')
    cookie.remove('customer_firstName')
    setTimeout(() => {
      updateCustomer()
    }, 300)
    setTimeout(() => {
      navigate('/')
    }, 500)
  })
}
Example #10
Source File: Hits.tsx    From checklist with MIT License 6 votes vote down vote up
Hits: FC<Props & HitsProvided<ChecklistHit>> = ({ hits, onClick }) => {
  const enterListener = (event: KeyboardEvent) => {
    if (event.key === 'Enter' && hits.length > 0) {
      navigate(`/checklist/${hits[0].slug}`);
    }
  };

  useLayoutEffect(() => {
    window.addEventListener('keyup', enterListener);

    return () => {
      window.removeEventListener('keyup', enterListener);
    };
  });

  return (
    <div className="c-search__hits">
      {hits.map(hit => (
        <SearchCard
          key={hit.objectID}
          category={hit.category}
          categorySlug={hit.categorySlug}
          todoCount={hit.todoCount}
          title={hit.title}
          description={hit.description}
          tags={hit.tags}
          slug={hit.slug}
          onClick={onClick}
        />
      ))}
    </div>
  );
}
Example #11
Source File: authWrapper.tsx    From midway with MIT License 6 votes vote down vote up
AuthWrapper = (props: Props) => {
  const { component: Component, path, ...rest } = props
  const [ready, setReady] = useState(false)

  useEffect(() => {
    if (!cookie.get('customer_token') || !cookie.get('customer_email')) navigate('/account/login')
    setReady(true)
  }, [0]);

  return (
    <div>
      {ready ? <Component path={path} {...rest} /> : <span />}
    </div>
  )
}
Example #12
Source File: index.tsx    From desktop with MIT License 6 votes vote down vote up
export default function Redirector(): ReactNode {
  const [onboardingDone] = useConfig(`hasRunOnboarding`)
  if (typeof window !== `undefined`) {
    if (onboardingDone) {
      navigate(`/sites`)
    } else {
      navigate(`/onboarding/intro`)
    }
  }

  return (
    <div
      sx={{
        width: `100vw`,
        height: `100vh`,
        backgroundColor: `purple.80`,
      }}
      onClick={(): Promise<void> => navigate(`/onboarding/intro`)}
    />
  )
}
Example #13
Source File: FloatingPrompt.tsx    From nyxo-website with MIT License 6 votes vote down vote up
FloatingPrompt: FC = () => {
  const { t } = useTranslation()
  const { language } = useI18next()
  const handleClick = () => {
    if (navigator.userAgent.toLowerCase().indexOf("android") > -1) {
      window.location.href =
        "https://play.google.com/store/apps/details?id=fi.nyxo.app&hl=en_US"
    }
    if (navigator.userAgent.toLowerCase().indexOf("iphone") > -1) {
      window.location.href =
        "https://apps.apple.com/us/app/nyxo-sleep-coaching/id1440417031"
    } else {
      navigate(`/${language === "fi" ? "fi/" : ""}for-you`)
    }
  }
  return (
    <Banner>
      <TextMobile>{t("PROMPT.MOBILE")}</TextMobile>
      <TextTablet>{t("PROMPT.TABLET")}</TextTablet>
      <TextDesktop>{t("PROMPT.DESKTOP")}</TextDesktop>
      <Button onClick={handleClick}>
        <ButtonText>{t("PROMPT.BUTTON")}</ButtonText>
        <Arrow />
      </Button>
    </Banner>
  )
}
Example #14
Source File: use-promotion-row-actions.tsx    From admin with MIT License 5 votes vote down vote up
usePromotionActions = (promotion) => {
  const notification = useNotification()
  const dialog = useImperativeDialog()

  const copyPromotion = useCopyPromotion()

  const updatePromotion = useAdminUpdateDiscount(promotion.id)
  const deletePromotion = useAdminDeleteDiscount(promotion?.id)

  const handleDelete = async () => {
    const shouldDelete = await dialog({
      heading: "Delete Discount",
      text: "Are you sure you want to delete this Discount?",
    })

    if (shouldDelete) {
      deletePromotion.mutate()
    }
  }

  const getRowActions = () => {
    return [
      {
        label: "Edit",
        icon: <EditIcon size={20} />,
        onClick: () => navigate(`/a/discounts/${promotion.id}`),
      },
      {
        label: promotion.is_disabled ? "Publish" : "Unpublish",
        icon: promotion.is_disabled ? (
          <PublishIcon size={20} />
        ) : (
          <UnpublishIcon size={20} />
        ),
        onClick: () => {
          updatePromotion.mutate(
            {
              is_disabled: !promotion.is_disabled,
            },
            {
              onSuccess: () => {
                notification(
                  "Success",
                  `Successfully ${
                    promotion.is_disabled ? "published" : "unpublished"
                  } discount`,
                  "success"
                )
              },
              onError: (err) =>
                notification("Error", getErrorMessage(err), "error"),
            }
          )
        },
      },
      {
        label: "Duplicate",
        icon: <DuplicateIcon size={20} />,
        onClick: () => copyPromotion(promotion),
      },
      {
        label: "Delete",
        icon: <TrashIcon size={20} />,
        variant: "danger",
        onClick: handleDelete,
      },
    ]
  }

  return { getRowActions }
}
Example #15
Source File: index.tsx    From gatsby-project-kb with MIT License 5 votes vote down vote up
export default function Search(props: SearchProps) {
  const { isMobileMode, resultsClassName, resultsWidth, onResults, position } = props
  const [query, setQuery] = useState('')
  const searchBarRef = useRef<HTMLDivElement>(null)
  const searchBarInputRef = useRef<HTMLInputElement>(null)

  const results = useSearch(query)

  const handleChange = useCallback((e) => setQuery(e.target.value), [setQuery])

  // if (searchActivateHotkey) {
  //   useHotkeys(searchActivateHotkey, () => {
  //     setTimeout(() => {
  //       if (searchBarInputRef.current) searchBarInputRef.current.focus()
  //     })
  //   })
  // }

  if (onResults) {
    useEffect(() => {
      onResults(results.filter((o) => o.id !== LOADING_ID))
    }, [results])
  }

  return (
    <Downshift
      onChange={(selection) => navigate(selection.path)}
      itemToString={(item) => (item ? item.title : '')}
    >
      {({
        getInputProps,
        getItemProps,
        getMenuProps,
        isOpen,
        highlightedIndex,
        getRootProps,
      }) => {
        return (
          <div
            className="searchWrapper"
            {...getRootProps({} as any, { suppressRefError: true })}
          >
            <SearchBar
              onChange={handleChange}
              getInputProps={getInputProps}
              ref={searchBarRef}
              inputRef={searchBarInputRef}
            />
            {isOpen && (
              <Results
                getMenuProps={getMenuProps}
                getItemProps={getItemProps}
                results={results}
                highlightedIndex={highlightedIndex}
                searchBarRef={searchBarRef}
                isMobileMode={isMobileMode}
                className={resultsClassName}
                position={position}
                width={resultsWidth}
              />
            )}
          </div>
        )
      }}
    </Downshift>
  )
}
Example #16
Source File: use-product-actions.tsx    From admin with MIT License 5 votes vote down vote up
useProductActions = (product) => {
  const notification = useNotification()
  const dialog = useImperativeDialog()
  const copyProduct = useCopyProduct()
  const deleteProduct = useAdminDeleteProduct(product?.id)
  const updateProduct = useAdminUpdateProduct(product?.id)

  const handleDelete = async () => {
    const shouldDelete = await dialog({
      heading: "Delete Product",
      text: "Are you sure you want to delete this product?",
    })

    if (shouldDelete) {
      deleteProduct.mutate()
    }
  }

  const getActions = (): ActionType[] => [
    {
      label: "Edit",
      onClick: () => navigate(`/a/products/${product.id}`),
      icon: <EditIcon size={20} />,
    },
    {
      label: product.status === "published" ? "Unpublish" : "Publish",
      onClick: () => {
        const newStatus = product.status === "published" ? "draft" : "published"
        updateProduct.mutate(
          {
            status: newStatus,
          },
          {
            onSuccess: () => {
              notification(
                "Success",
                `Successfully ${
                  product.status === "published" ? "unpublished" : "published"
                } product`,
                "success"
              )
            },
            onError: (err) =>
              notification("Error", getErrorMessage(err), "error"),
          }
        )
      },
      icon:
        product.status === "published" ? (
          <UnpublishIcon size={20} />
        ) : (
          <PublishIcon size={20} />
        ),
    },
    {
      label: "Duplicate",
      onClick: () => copyProduct(product),
      icon: <DuplicateIcon size={20} />,
    },
    {
      label: "Delete",
      variant: "danger",
      onClick: handleDelete,
      icon: <TrashIcon size={20} />,
    },
  ]

  return {
    getActions,
  }
}
Example #17
Source File: index.ts    From pola-web with MIT License 5 votes vote down vote up
navigateTo = (url: string) => {
  if (isBrowserEnv()) {
    navigate(url);
  }
}
Example #18
Source File: topmenu.tsx    From website with MIT License 5 votes vote down vote up
useMainMenuItems = (verticalLayout: boolean) => {
	const createSubMenu = (title, children) => {
		const menuKey = title.toLowerCase().replace(/[^a-z0-9_]/g, '');
		if (verticalLayout) {
			return (
				<Menu.Item key={`/${menuKey}`}>
					<Menu.Header>{title}</Menu.Header>
					<Menu.Menu>
						{children.map(item => (
							<Menu.Item key={`${menuKey}${item.link}`} onClick={() => navigate(item.link)}>
								{item.title}
							</Menu.Item>
						))}
					</Menu.Menu>
				</Menu.Item>
			);
		} else {
			return (
				<Dropdown key={`/${menuKey}`} item simple text={title}>
					<Dropdown.Menu>
						{children.map(item => (
							<Dropdown.Item key={`${menuKey}${item.link}`} onClick={() => navigate(item.link)}>
								{item.title}
							</Dropdown.Item>
						))}
					</Dropdown.Menu>
				</Dropdown>
			);
		}
	};

	let items = [
		<Menu.Item key='/' onClick={() => navigate('/')}>
			Crew stats
		</Menu.Item>,
		<Menu.Item key='/behold' onClick={() => navigate('/behold')}>
			Behold
		</Menu.Item>
	];

	items.push(createSubMenu('Player tools', Object.entries(playerTools).map(([key, value]) => ({
			title: value.title,
			link: `/playertools?tool=${key}`
		})))
	);

	const pages = [
		{ title: 'Events', link: '/events' },
		{ title: 'Collections', link: '/collections' },
		{ title: 'Items', link: '/items' },
		{ title: 'Misc stats', link: '/stats' },
		{ title: 'Episodes', link: '/episodes' },
		{ title: 'Hall of Fame', link: '/hall_of_fame' },
		{ title: 'Worfle', link: '/crewchallenge' }
	];
	items.push(createSubMenu('Pages', pages));

	items.push(<Menu.Item key='bigbook' onClick={() => navigate('https://bigbook.app')}>Big book</Menu.Item>);

	const about = [
		{ title: 'About DataCore', link: '/about' },
		{ title: 'Announcements', link: '/announcements' }
	];
	// Show other markdowns as discovered by Gatsby in About menu
	const otherPages = useOtherPages();
	otherPages.map((page) => {
		about.push(
			{ title: page.title, link: page.slug }
		);
	});
	items.push(createSubMenu('About', about));

	if (verticalLayout) {
		return items;
	} else {
		return <Container>{items}</Container>;
	}
}
Example #19
Source File: use-copy-promotion.tsx    From admin with MIT License 5 votes vote down vote up
useCopyPromotion = () => {
  const notification = useNotification()
  const createPromotion = useAdminCreateDiscount()

  const handleCopyPromotion = async (promotion) => {
    const copy: any = {
      code: `${promotion.code}_COPY`,
      is_disabled: promotion.is_disabled,
      is_dynamic: promotion.is_dynamic,
      starts_at: promotion.starts_at,
      regions: promotion.regions.map((region) => region.id),
    }

    if (promotion.ends_at) {
      copy.ends_at = promotion.ends_at
    }

    if (promotion.valid_duration) {
      copy.valid_duration = promotion.valid_duration
    }

    if (typeof promotion.usage_limit === "number") {
      copy.usage_limit = promotion.usage_limit
    }

    if (promotion.metadata) {
      copy.metadata = promotion.metadata
    }

    copy.rule = {
      type: promotion.rule.type,
      value: promotion.rule.value,
      description: promotion.rule.description,
    }

    if (promotion.rule.allocation) {
      copy.rule.allocation = promotion.rule.allocation
    }

    if (promotion.rule.conditions) {
      copy.rule.conditions = promotion.rule.conditions.map((cond) => ({
        operator: cond.operator,
        ...removeNullish({
          products: cond.products,
          product_types: cond.product_types,
          product_tags: cond.product_tags,
          product_collections: cond.product_collections,
          customer_groups: cond.customer_groups,
        }),
      }))
    }

    await createPromotion.mutate(copy, {
      onSuccess: (result) => {
        navigate(`/a/discounts/${result.discount.id}`)
        notification("Success", "Successfully copied discount", "success")
      },
      onError: (err) => {
        notification("Error", getErrorMessage(err), "error")
      },
    })
  }

  return handleCopyPromotion
}
Example #20
Source File: TableOfContents.tsx    From mantine with MIT License 5 votes vote down vote up
export default function TableOfContents({ headings, withTabs }: TableOfContentsProps) {
  const theme = useMantineTheme();
  const { classes, cx } = useStyles();
  const slugger = new Slugger();
  const [active, setActive] = useState(0);
  const { pathname } = useLocation();

  const slugs = useRef<HTMLDivElement[]>([]);
  const filteredHeadings = headings.filter((heading) => heading.depth > 1);

  useEffect(() => {
    slugger.reset();
    slugs.current = filteredHeadings.map(
      (heading) => document.getElementById(slugger.slug(heading.value)) as HTMLDivElement
    );
  }, [headings]);

  const handleScroll = () => {
    setActive(getActiveElement(slugs.current.map((d) => d.getBoundingClientRect())));
  };

  useEffect(() => {
    setActive(getActiveElement(slugs.current.map((d) => d.getBoundingClientRect())));
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  if (filteredHeadings.length === 0) {
    return null;
  }

  const items = filteredHeadings.map((heading, index) => {
    const slug = slugger.slug(heading.value);
    return (
      <Text<'a'>
        key={slug}
        component="a"
        size="sm"
        className={cx(classes.link, { [classes.linkActive]: active === index })}
        href={`#${slug}`}
        sx={{ paddingLeft: (heading.depth - 1) * theme.spacing.lg }}
        onClick={(event) => {
          event.preventDefault();
          navigate(`${pathname}#${slug}`, { replace: true });
        }}
      >
        {heading.value}
      </Text>
    );
  });

  return (
    <nav className={cx(classes.wrapper, { [classes.withTabs]: withTabs })}>
      <div className={classes.inner}>
        <div>
          <div className={classes.header}>
            <ActivityLogIcon />
            <Text className={classes.title}>Table of contents</Text>
          </div>
          <div className={classes.items}>{items}</div>
        </div>
      </div>
    </nav>
  );
}
Example #21
Source File: tab-navigation.tsx    From desktop with MIT License 5 votes vote down vote up
export function SiteTabLink({ site, ...props }: ITabProps): JSX.Element {
  const { removeTab } = useSiteTabs()

  const location = useLocation()

  const url = `/sites/${site.hash}`

  const isActive = location.pathname === url

  const remove = useCallback(() => {
    if (isActive) {
      navigate(`/sites`)
    }
    removeTab(site.hash)
  }, [removeTab, site, isActive])

  return (
    <Flex
      sx={{
        alignItems: `center`,
        pr: 2,
        py: 3,
        ...(isActive && {
          backgroundColor: `purple.80`,
          color: `white`,
        }),
      }}
    >
      <TabLink {...props} to={url}>
        <SiteStatusDot status={site.siteStatus.status} sx={{ mr: 2 }} />
        {site.name}
      </TabLink>
      <button
        onClick={remove}
        aria-label="Close tab"
        sx={{
          p: 3,
          background: `none`,
          border: `none`,
          fontFamily: `sans`,
          fontWeight: 500,
          textDecoration: `none`,
          color: `primaryBackground`,
          display: `flex`,
          alignItems: `center`,
        }}
      >
        <MdClear />
      </button>
    </Flex>
  )
}
Example #22
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
LoginCard: React.FC<LoginCardProps> = ({ toResetPassword }) => {
  const [isInvalidLogin, setIsInvalidLogin] = useState(false)
  const { register, handleSubmit, reset } = useForm<FormValues>()
  const login = useAdminLogin()

  const onSubmit = (values: FormValues) => {
    login.mutate(values, {
      onSuccess: () => {
        navigate("/a/orders")
      },
      onError: () => {
        setIsInvalidLogin(true)
        reset()
      },
    })
  }
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div className="flex flex-col items-center">
        <span className="inter-2xlarge-semibold mt-4 text-grey-90">
          Welcome back!
        </span>
        <span className="inter-base-regular text-grey-50 mt-2">
          It's great to see you ??
        </span>
        <span className="inter-base-regular text-grey-50 mb-xlarge">
          Log in to your account below
        </span>
        <SigninInput
          placeholder="Email..."
          name="email"
          ref={register({ required: true })}
          autoComplete="email"
        />
        <SigninInput
          placeholder="Password..."
          type={"password"}
          name="password"
          ref={register({ required: true })}
          autoComplete="current-password"
        />
        {isInvalidLogin && (
          <span className="text-rose-50 w-full mt-2 inter-small-regular">
            These credentials do not match our records
          </span>
        )}
        <Button
          className="rounded-rounded mt-4 w-[320px] inter-base-regular"
          variant="primary"
          size="large"
          type="submit"
          loading={login.isLoading}
        >
          Continue
        </Button>
        <span
          className="inter-small-regular text-grey-50 mt-8 cursor-pointer"
          onClick={toResetPassword}
        >
          Reset password
        </span>
      </div>
    </form>
  )
}
Example #23
Source File: UserInfo.tsx    From nyxo-website with MIT License 5 votes vote down vote up
UserInfo: FC = () => {
  const { data } = useGetUser()
  const { t } = useTranslation()
  console.log("user", data)
  const signOut = () => {
    Auth.signOut()
      .then(function () {
        navigate("/me/login")
      })
      ["catch"](function (err) {
        console.error(err)
      })
  }

  return (
    <Container>
      <Row>
        <H3>{data?.nickname ?? "You"}</H3>
        <Button onClick={signOut}>
          <Icon name="logout" height="30px" width="30px" />
          <ButtonText>Logout</ButtonText>
        </Button>
      </Row>

      <H5>Information</H5>
      <DetailRow>
        <Title>{`${t("USER.EMAIL")}:`}</Title>
        <Detail>{`${data?.email}`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.ID")}:`}</Title>
        <Detail>{`${data?.id}`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.INTERCOM")}:`}</Title>
        <Detail>{`${data?.intercomId}`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.LINK")}:`}</Title>
        <Detail>{`${data?.connectionId}`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.ACTIVE_COACHING")}:`}</Title>
        <Detail>{`${
          data?.activeCoaching?.started &&
          format(new Date(data?.activeCoaching.started as string), dateFormat)
        }`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.CREATED")}:`}</Title>
        <Detail>{`${
          data?.createdAt &&
          format(new Date(data?.createdAt as string), dateFormat)
        }`}</Detail>
      </DetailRow>
      <DetailRow>
        <Title>{`${t("USER.UPDATED")}:`}</Title>
        <Detail>{`${
          data?.updatedAt &&
          format(new Date(data?.updatedAt as string), dateFormat)
        }`}</Detail>
      </DetailRow>
    </Container>
  )
}
Example #24
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
Topbar: React.FC = () => {
  const { first_name, last_name, email, handleLogout } = useContext(
    AccountContext
  )

  const [showSupportform, setShowSupportForm] = useState(false)

  const logOut = () => {
    handleLogout()
    navigate("/login")
  }

  return (
    <div className="w-full min-h-topbar max-h-topbar pr-xlarge pl-base bg-grey-0 border-b border-grey-20 sticky top-0 flex items-center justify-between z-40">
      <SearchBar />
      <div className="flex items-center">
        <Button
          size="small"
          variant="ghost"
          className="w-8 h-8 mr-3"
          onClick={() => setShowSupportForm(!showSupportform)}
        >
          <HelpCircleIcon size={24} />
        </Button>
        <NotificationBell hasNotifications={false} />
        <div className="ml-large w-large h-large">
          <DropdownMenu.Root>
            <DropdownMenu.Trigger asChild>
              <div className="cursor-pointer w-full h-full">
                <Avatar
                  user={{ first_name, last_name, email }}
                  color="bg-fuschia-40"
                />
              </div>
            </DropdownMenu.Trigger>
            <DropdownMenu.Content
              sideOffset={5}
              className="border bg-grey-0 border-grey-20 rounded-rounded shadow-dropdown p-xsmall min-w-[200px] z-30"
            >
              <DropdownMenu.Item className="mb-1 last:mb-0">
                <Button
                  variant="ghost"
                  size="small"
                  className={"w-full justify-start"}
                  onClick={() => navigate("/a/settings")}
                >
                  <GearIcon />
                  Settings
                </Button>
                <Button
                  variant="ghost"
                  size="small"
                  className={"w-full justify-start text-rose-50"}
                  onClick={() => logOut()}
                >
                  <SignOutIcon size={20} />
                  Sign out
                </Button>
              </DropdownMenu.Item>
            </DropdownMenu.Content>
          </DropdownMenu.Root>
        </div>
      </div>
      {showSupportform && (
        <MailDialog onDismiss={() => setShowSupportForm(false)} />
      )}
    </div>
  )
}
Example #25
Source File: edit.tsx    From j3pz-web with MIT License 5 votes vote down vote up
componentDidMount() {
        const caseId = window.location.hash.replace('#', '');
        if (caseId) {
            CaseService.getCase(caseId).then((res) => {
                if (res) {
                    const detail = CaseDetail.fromJson(res.attributes);
                    CaseService.applyToStore(detail);
                    EmbedService.update($store);
                } else {
                    navigate('/dashboard');
                }
            });
        } else {
            Alert.warning('这是一个临时界面,配装方案仅能在当前设备上进行修改而无法保存。', 10000);
        }
        if (!this.props.store.user) {
            UserService.getUser(false).then((res) => {
                if (res) {
                    transaction(() => {
                        $store.user = User.fromJson(res.attributes);
                        $store.settings.autoStrengthen = !!res.attributes.preference.strengthen;
                        $store.settings.autoEmbed = res.attributes.preference.magicStoneLevel;
                    });
                }
            });
        }
        SettingsService.getAnnouncement().then((res) => {
            const checkedVersion = localStorage.getItem('announcement');
            if (res?.version && res?.version !== checkedVersion) {
                Notification.open({
                    key: 'announcement',
                    title: res.title ?? '公告',
                    description: res.content,
                    duration: 0,
                    placement: 'bottomEnd',
                });
                localStorage.setItem('announcement', res.version);
            }
        });
    }
Example #26
Source File: customers-list-table.tsx    From admin with MIT License 5 votes vote down vote up
/*
 * Renders customer group customers list table row.
 */
function CustomersListTableRow(props: CustomersListTableRowProps) {
  const { row, removeCustomers } = props

  const actions = [
    {
      label: "Details",
      onClick: () => navigate(`/a/customers/${row.original.id}`),
      icon: <DetailsIcon size={20} />,
    },
    // {
    //   label: "Send an email",
    //   onClick: () => window.open(`mailto:${row.original.email}`),
    //   icon: <MailIcon size={20} />,
    // },
    {
      label: "Delete from the group",
      variant: "danger",
      onClick: () =>
        removeCustomers({
          customer_ids: [{ id: row.original.id }],
        }),
      icon: <TrashIcon size={20} />,
    },
  ]

  return (
    <Table.Row
      color={"inherit"}
      actions={actions}
      linkTo={`/a/customers/${props.row.original.id}`}
      {...props.row.getRowProps()}
    >
      {props.row.cells.map((cell, index) => (
        <Table.Cell {...cell.getCellProps()}>
          {cell.render("Cell", { index })}
        </Table.Cell>
      ))}
    </Table.Row>
  )
}
Example #27
Source File: index.tsx    From gatsby-project-kb with MIT License 4 votes vote down vote up
export default function GraphView({
  setGraphState,
  graphState,
  currentFileId,
  isMobileMode,
}: Props) {
  const { notesMap, fileNodesMap } = useGraphData()
  const windowSize = useWindowSize()
  const graphContainer = useRef<HTMLDivElement>(null)
  const shouldShowGraph = graphState !== 'hidden'

  const modalShrinkSizeX = isMobileMode ? 20: 40
  const modalShrinkSizeY = isMobileMode ? 80: 40
  const modalSize = {
    width: Math.min(windowSize.width - modalShrinkSizeX, 1400),
    height: Math.min(windowSize.height - modalShrinkSizeY, 800),
  }

  const navigateTo = (p: string) => {
    navigate(p)
  }

  const notes = Array.from(notesMap.values())
  let noteGraphView: NoteGraphView

  useEffect(() => {
    if (!graphContainer.current || graphState === 'hidden') {
      return
    }

    const graphModel = new NoteGraphModel(notes)

    noteGraphView = new NoteGraphView({
      container: graphContainer.current,
      graphModel,
      width: isMobileMode ? modalSize.width : modalSize.width - RESULTS_WIDTH,
      height: modalSize.height,
    })

    noteGraphView.onInteraction('nodeClick', ({ node }) => {
      const fileNode = fileNodesMap.get(node.id)
      const slug = fileNode?.fields?.slug
      if (slug) {
        navigateTo(slug)
      }
    })

    if (currentFileId) {
      const currentNoteInfo = graphModel.getNodeInfoById(currentFileId)
      const shouldZoomToFit = currentNoteInfo && Boolean(currentNoteInfo.neighbors?.length)
      noteGraphView.setSelectedNodes([currentFileId], { shouldZoomToFit })
    }

    return () => {
      noteGraphView.dispose()
    }
  }, [notes, graphState])

  useHotkeys('Escape Escape', () => {
    setGraphState('hidden')
  })

  const onSearchResults: SearchProps['onResults'] = (results) => {
    if (noteGraphView) {
      const nodeIds = results.map((o) => o.id).filter((s) => s)
      // console.debug('onSearchResults node ids', nodeIds)
      // It's better to add another highlight style or specity styles in `setSelectedNodes`,
      //   I will need to extend note-graph for this.
      if (nodeIds.length) {
        noteGraphView.setSelectedNodes(nodeIds)
      } else {
        noteGraphView.setSelectedNodes([currentFileId])
      }
    }
  }

  return createPortal(
    <div>
      <div
        aria-hidden
        className={`overlay ${shouldShowGraph ? 'show' : ''}`}
        onClick={(ev) => {
          if (!ev.isDefaultPrevented()) {
            setGraphState('hidden')
          }
        }}
      />

      <div
        className={`graph-view__modal modal-${graphState}`}
        onClick={(ev) => ev.preventDefault()}
        style={{ display: shouldShowGraph ? 'flex' : 'none' }}
      >
        <div
          style={{
            width: modalSize.width,
            height: modalSize.height,
          }}
        >
          <button
            className="modal-close"
            type="button"
            onClick={() => {
              setGraphState('hidden')
            }}
            aria-label="Close Graph"
          >
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M11.997 9.90045L20.9 1L23 3.09955L14.097 12L23 20.9005L20.9 23L11.997 14.0995L3.10001 22.994L1 20.8944L9.89699 12L1 3.10558L3.10001 1.00603L11.997 9.90045Z" />
            </svg>
          </button>
          <div className="modal-body">
            <div className="flex">
              {!isMobileMode && (
                <div className="graph-view__search-wrap w-3/12">
                  <Search
                    position="right"
                    resultsClassName="graph-view__search-results"
                    resultsWidth={RESULTS_WIDTH}
                    onResults={onSearchResults}
                  ></Search>
                </div>
              )}
              <div>
                <div ref={graphContainer} id="graph-container"></div>
                <div className="graph-view__modal-hint">Press Esc twice to
                  <button
                    type="button"
                    className="graph-view__btn--link"
                    onClick={() => {
                      setGraphState('hidden')
                    }}
                    aria-label="Close Graph"
                  >close</button>
                 this modal.
                 </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>,
    document.body
  )
}
Example #28
Source File: profile_crew.tsx    From website with MIT License 4 votes vote down vote up
ProfileCrewTable = (props: ProfileCrewTableProps) => {
	const pageId = props.pageId ?? 'crew';
	const [showFrozen, setShowFrozen] = useStateWithStorage(pageId+'/showFrozen', true);
	const [findDupes, setFindDupes] = useStateWithStorage(pageId+'/findDupes', false);

	const myCrew = JSON.parse(JSON.stringify(props.crew));

	const tableConfig: ITableConfigRow[] = [
		{ width: 3, column: 'name', title: 'Crew', pseudocolumns: ['name', 'events', 'collections.length'] },
		{ width: 1, column: 'max_rarity', title: 'Rarity', reverse: true, tiebreakers: ['rarity'] },
		{ width: 1, column: 'bigbook_tier', title: 'Tier' },
		{ width: 1, column: 'cab_ov', title: <span>CAB <CABExplanation /></span>, reverse: true, tiebreakers: ['cab_ov_rank'] },
		{ width: 1, column: 'ranks.voyRank', title: 'Voyage' }
	];
	CONFIG.SKILLS_SHORT.forEach((skill) => {
		tableConfig.push({
			width: 1,
			column: `${skill.name}.core`,
			title: <img alt={CONFIG.SKILLS[skill.name]} src={`${process.env.GATSBY_ASSETS_URL}atlas/icon_${skill.name}.png`} style={{ height: '1.1em' }} />,
			reverse: true
		});
	});

	function showThisCrew(crew: any, filters: [], filterType: string): boolean {
		if (!showFrozen && crew.immortal > 0) {
			return false;
		}

		if (findDupes) {
			if (myCrew.filter((c) => c.symbol === crew.symbol).length === 1)
				return false;
		}

		return crewMatchesSearchFilter(crew, filters, filterType);
	}

	function renderTableRow(crew: any, idx: number, highlighted: boolean): JSX.Element {
		const attributes = {
			positive: highlighted
		};

		return (
			<Table.Row key={idx} style={{ cursor: 'zoom-in' }} onClick={() => navigate(`/crew/${crew.symbol}/`)} {...attributes}>
				<Table.Cell>
					<div
						style={{
							display: 'grid',
							gridTemplateColumns: '60px auto',
							gridTemplateAreas: `'icon stats' 'icon description'`,
							gridGap: '1px'
						}}
					>
						<div style={{ gridArea: 'icon' }}>
							<img width={48} src={`${process.env.GATSBY_ASSETS_URL}${crew.imageUrlPortrait}`} />
						</div>
						<div style={{ gridArea: 'stats' }}>
							<span style={{ fontWeight: 'bolder', fontSize: '1.25em' }}><Link to={`/crew/${crew.symbol}/`}>{crew.name}</Link></span>
						</div>
						<div style={{ gridArea: 'description' }}>{descriptionLabel(crew)}</div>
					</div>
				</Table.Cell>
				<Table.Cell>
					<Rating icon='star' rating={crew.rarity} maxRating={crew.max_rarity} size="large" disabled />
				</Table.Cell>
				<Table.Cell textAlign="center">
					<b>{formatTierLabel(crew.bigbook_tier)}</b>
				</Table.Cell>
				<Table.Cell style={{ textAlign: 'center' }}>
					<b>{crew.cab_ov}</b><br />
					<small>{rarityLabels[parseInt(crew.max_rarity)-1]} #{crew.cab_ov_rank}</small>
				</Table.Cell>
				<Table.Cell style={{ textAlign: 'center' }}>
					<b>#{crew.ranks.voyRank}</b><br />
					{crew.ranks.voyTriplet && <small>Triplet #{crew.ranks.voyTriplet.rank}</small>}
				</Table.Cell>
				{CONFIG.SKILLS_SHORT.map(skill =>
					crew[skill.name].core > 0 ? (
						<Table.Cell key={skill.name} textAlign='center'>
							<b>{crew[skill.name].core}</b>
							<br />
							+({crew[skill.name].min}-{crew[skill.name].max})
						</Table.Cell>
					) : (
						<Table.Cell key={skill.name} />
					)
				)}
			</Table.Row>
		);
	}

	function descriptionLabel(crew: any): JSX.Element {
		if (crew.immortal) {
			return (
				<div>
					<Icon name="snowflake" /> <span>{crew.immortal} frozen</span>
				</div>
			);
		} else {
			const counts = [
				{ name: 'event', count: crew.events },
				{ name: 'collection', count: crew.collections.length }
			];
			const formattedCounts = counts.map((count, idx) => (
				<span key={idx} style={{ whiteSpace: 'nowrap' }}>
					{count.count} {count.name}{count.count != 1 ? 's' : ''}{idx < counts.length-1 ? ',' : ''}
				</span>
			)).reduce((prev, curr) => [prev, ' ', curr]);

			return (
				<div>
					{crew.favorite && <Icon name="heart" />}
					{crew.prospect && <Icon name="add user" />}
					<span>Level {crew.level}, </span>
					{formattedCounts}
				</div>
			);
		}
	}

	return (
		<React.Fragment>
			<div style={{ margin: '.5em 0' }}>
				<Form.Group grouped>
					<Form.Field
						control={Checkbox}
						label='Show frozen (vaulted) crew'
						checked={showFrozen}
						onChange={(e, { checked }) => setShowFrozen(checked)}
					/>
					<Form.Field
						control={Checkbox}
						label='Only show duplicate crew'
						checked={findDupes}
						onChange={(e, { checked }) => setFindDupes(checked)}
					/>
				</Form.Group>
			</div>
			<SearchableTable
				id={`${pageId}/table_`}
				data={myCrew}
				config={tableConfig}
				renderTableRow={(crew, idx, highlighted) => renderTableRow(crew, idx, highlighted)}
				filterRow={(crew, filters, filterType) => showThisCrew(crew, filters, filterType)}
				showFilterOptions="true"
				initOptions={props.initOptions}
				lockable={props.lockable}
			/>
		</React.Fragment>
	);
}
Example #29
Source File: RiskLevelIndicator.tsx    From Frontend with MIT License 4 votes vote down vote up
RiskLevelIndicator: React.FC<RiskLevelIndicatorProps> = ({ uid }) => {
  //TODO get value from api on medical status
  const defaultValue = 15;

  const checkRiskStatus = () => {
    let riskStatus = riskLevelOptions[0];

    // Check riskStatus based on risk indicator number from api
    switch (true) {
      case defaultValue >= 0 && defaultValue < 25:
        break;
      case defaultValue >= 25 && defaultValue < 50:
        riskStatus = riskLevelOptions[1];

        break;
      case defaultValue >= 50 && defaultValue < 75:
        riskStatus = riskLevelOptions[2];
        break;

      case defaultValue >= 75:
        riskStatus = riskLevelOptions[3];
        break;

      default:
        break;
    }

    return (
      <Flex flexDirection="row" width="100%" rounded="sm">
        <Flex
          justifyContent="center"
          w="40%"
          p="8"
          bg={riskStatus.color}
          color="white"
        >
          <Text color="white" fontSize="xl" fontWeight="bold">
            {riskStatus.level}
          </Text>
        </Flex>

        <Flex
          justifyContent="center"
          alignItems="center"
          w="60%"
          p="8"
          border="2px"
          borderColor={riskStatus.color}
        >
          {riskStatus.message}
        </Flex>
      </Flex>
    );
  };

  return (
    <Flex
      flexDirection="column"
      p={5}
      my={12}
      shadow="sm"
      borderWidth="1px"
      justify="center"
      align="center"
    >
      <Lead>
        <FormattedMessage id="RiskLevel.heading" />
      </Lead>
      {/* {checkRiskStatus()} */}

      {/* <Slider size="lg" defaultValue={defaultValue}>
        <SliderTrack bg="red.100" />
        <SliderFilledTrack bg="tomato" />
        <SliderThumb size={6} />
      </Slider> */}

      <Button
        onClick={() => navigate('/me/log')}
        variantColor="teal"
        type="button"
      >
        <FormattedMessage id="RiskLevel.cta" />
      </Button>
    </Flex>
  );
}