@reach/router#RouteComponentProps TypeScript Examples

The following examples show how to use @reach/router#RouteComponentProps. 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: IModelsRoute.tsx    From viewer with MIT License 6 votes vote down vote up
IModelsRoute = ({
  iTwinId,
  location,
}: RouteComponentProps<IModelsRouteParams>) => {
  const [projectName, setProjectName] = useState<string>();
  const [pendingIModel, setPendingIModel] = useState<string>();
  const accessToken = useAccessToken();

  useEffect(() => {
    const routeState = location?.state as IModelsRouteState | undefined;
    if (routeState?.projectName) {
      setProjectName(routeState?.projectName);
    }
  }, [location?.state]);

  return (
    <IModelContext.Provider value={{ pendingIModel, setPendingIModel }}>
      {accessToken ? (
        <SelectIModel
          accessToken={accessToken}
          projectId={iTwinId}
          projectName={projectName}
        />
      ) : (
        <SignIn />
      )}
    </IModelContext.Provider>
  );
}
Example #2
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
CustomerIndex: React.FC<RouteComponentProps> = () => {
  return (
    <div className="flex flex-col grow h-full">
      <div className="w-full flex flex-col grow">
        <BodyCard
          customHeader={<CustomersPageTableHeader activeView="customers" />}
        >
          <CustomerTable />
        </BodyCard>
      </div>
    </div>
  )
}
Example #3
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
/*
 * Customer groups routes
 */
function CustomerGroups(_: RouteComponentProps) {
  return (
    <CustomerGroupContextContainer>
      <Router basepath="/a/customers/groups">
        <Index path="/" />
        <Details path=":id" />
      </Router>
    </CustomerGroupContextContainer>
  )
}
Example #4
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
/*
 * Customer groups index page
 */
function Index(_: RouteComponentProps) {
  const { showModal } = useContext(CustomerGroupContext)

  const actions = [
    {
      label: "New group",
      onClick: showModal,
      icon: (
        <span className="text-grey-90">
          <PlusIcon size={20} />
        </span>
      ),
    },
  ]

  return (
    <div className="flex flex-col grow h-full">
      <div className="w-full flex flex-col grow">
        <BodyCard
          actionables={actions}
          customHeader={<CustomersPageTableHeader activeView="groups" />}
        >
          <CustomerGroupsTable />
        </BodyCard>
      </div>
    </div>
  )
}
Example #5
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
DiscountIndex: React.FC<RouteComponentProps> = () => {
  const [isOpen, setIsOpen] = useState(false)

  const actionables = [
    {
      label: "Add Discount",
      onClick: () => setIsOpen(true),
      icon: <PlusIcon size={20} />,
    },
  ]

  return (
    <div className="h-full flex flex-col">
      <div className="w-full flex flex-col grow">
        <BodyCard
          actionables={actionables}
          customHeader={<TableViewHeader views={["discounts"]} />}
        >
          <DiscountTable />
        </BodyCard>
      </div>
      <DiscountFormProvider>
        <Fade isVisible={isOpen} isFullScreen={true}>
          <DiscountForm closeForm={() => setIsOpen(false)} />
        </Fade>
      </DiscountFormProvider>
    </div>
  )
}
Example #6
Source File: IModelsRoute.tsx    From viewer with MIT License 6 votes vote down vote up
IModelsRoute = ({
  iTwinId,
  location,
}: RouteComponentProps<IModelsRouteParams>) => {
  const [projectName, setProjectName] = useState<string>();
  const [pendingIModel, setPendingIModel] = useState<string>();
  const accessToken = useAccessToken();

  useEffect(() => {
    const routeState = location?.state as IModelsRouteState | undefined;
    if (routeState?.projectName) {
      setProjectName(routeState?.projectName);
    }
  }, [location?.state]);

  return (
    <IModelContext.Provider value={{ pendingIModel, setPendingIModel }}>
      {accessToken ? (
        <SelectIModel
          accessToken={accessToken}
          projectId={iTwinId}
          projectName={projectName}
        />
      ) : (
        <SignIn />
      )}
    </IModelContext.Provider>
  );
}
Example #7
Source File: HomeRoute.tsx    From viewer with MIT License 6 votes vote down vote up
HomeRoute = ({}: RouteComponentProps) => {
  const navigate = useNavigate();
  const userSettings = useContext(SettingsContext);

  useEffect(() => {
    // must be initialized here (child of the Router) in order to use the navigate function
    ITwinViewerApp.initializeMenuListeners(navigate, userSettings);
  }, []);

  return <Home />;
}
Example #8
Source File: HomeRoute.tsx    From viewer with MIT License 6 votes vote down vote up
HomeRoute = ({}: RouteComponentProps) => {
  const navigate = useNavigate();
  const userSettings = useContext(SettingsContext);

  useEffect(() => {
    // must be initialized here (child of the Router) in order to use the navigate function
    ITwinViewerApp.initializeMenuListeners(navigate, userSettings);
  }, []);

  return <Home />;
}
Example #9
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
OrderIndex: React.FC<RouteComponentProps> = () => {
  const view = "orders"

  const actions = useMemo(() => {
    return []
  }, [view])

  return (
    <div className="flex flex-col grow h-full">
      <div className="w-full flex flex-col grow">
        <BodyCard
          customHeader={
            <TableViewHeader
              views={VIEWS}
              setActiveView={(v) => {
                if (v === "drafts") {
                  navigate(`/a/draft-orders`)
                }
              }}
              activeView={view}
            />
          }
          actionables={actions}
        >
          <OrderTable />
        </BodyCard>
      </div>
    </div>
  )
}
Example #10
Source File: Home.tsx    From baleen3 with Apache License 2.0 6 votes vote down vote up
Home: React.FC<RouteComponentProps> = ({ navigate }) => (
  <>
    <Header>
      {{
        main: (
          <MainAction
            onClick={async (): Promise<void> => {
              if (navigate !== undefined) {
                await navigate('/new')
              }
            }}
            icon={<Icons.NewReleases />}
          >
            New Pipeline
          </MainAction>
        ),
      }}
    </Header>
    <Page data-testid="Home">
      <PipelinesContainer />
    </Page>
  </>
)
Example #11
Source File: index.tsx    From admin with MIT License 6 votes vote down vote up
PricingIndex: React.FC<RouteComponentProps> = () => {
  const actionables = [
    {
      label: "Add price list",
      onClick: () => navigate(`/a/pricing/new`),
      icon: <PlusIcon size={20} />,
    },
  ]

  return (
    <div className="h-full flex flex-col">
      <div className="w-full flex flex-col grow">
        <BodyCard
          actionables={actionables}
          customHeader={<TableViewHeader views={["Price lists"]} />}
        >
          <PricingTable />
        </BodyCard>
      </div>
    </div>
  )
}
Example #12
Source File: PageNotFound.tsx    From office-booker with MIT License 6 votes vote down vote up
PageNotFound: React.FC<RouteComponentProps> = () => {
  // Local state
  const [activateRedirect, setActivateRedirect] = useState(false);

  // Effects
  useEffect(() => {
    setTimeout(() => {
      setActivateRedirect(true);
    }, 5000);
  }, []);

  // Render
  return (
    <Layout>
      <ErrorPageStyles>
        <h2>Page Not Found</h2>
        <p>We&apos;ll redirect you to home in 5 seconds</p>

        {activateRedirect && <Redirect to="/" noThrow />}

        <OurButton
          type="submit"
          variant="contained"
          color="primary"
          onClick={() => {
            navigate(`/`);
          }}
        >
          Redirect Now
        </OurButton>
      </ErrorPageStyles>
    </Layout>
  );
}
Example #13
Source File: SignInView.tsx    From Frontend with MIT License 5 votes vote down vote up
LoginView: React.FC<RouteComponentProps> = (props) => {
  const { search } = useLocation();
  const { locationStore } = useStores();
  const intl = useIntl();

  const queryParams = queryString.parse(search) as any;

  if (queryParams.next) {
    locationStore.setNext(queryParams.next);
  } else {
    locationStore.setNext('/me');
  }

  console.log(props);

  return (
    <>
      <PageHeader
        heading={intl.formatMessage({ id: 'SigninView.heading' })}
        lead={intl.formatMessage({ id: 'SigninView.lead' })}
      />
      <FormState.Provider>
        <Tabs variant="soft-rounded" variantColor="teal">
          <TabList>
            <Tab>Sign In</Tab>
            <Tab>Sign Up</Tab>
          </TabList>

          <TabPanels>
            <TabPanel>
              <SignInForm></SignInForm>
            </TabPanel>
            <TabPanel>
              <SignUpForm></SignUpForm>
            </TabPanel>
          </TabPanels>
        </Tabs>

        <Form
          onLoginSuccess={(user) => {
            navigate('/me');
          }}
        ></Form>
      </FormState.Provider>
    </>
  );
}
Example #14
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
DraftOrderIndex: React.FC<RouteComponentProps> = () => {
  const view = "drafts"
  const [showNewOrder, setShowNewOrder] = useState(false)

  const actions = useMemo(() => {
    return [
      {
        label: "Create draft order",
        onClick: () => setShowNewOrder(true),
        icon: <PlusIcon size={20} />,
      },
    ]
  }, [view])

  return (
    <div className="flex flex-col grow h-full">
      <div className="w-full flex flex-col grow">
        <BodyCard
          customHeader={
            <TableViewHeader
              views={VIEWS}
              setActiveView={(v) => {
                if (v === "orders") {
                  navigate(`/a/orders`)
                }
              }}
              activeView={view}
            />
          }
          actionables={actions}
        >
          <DraftOrderTable />
        </BodyCard>
      </div>
      {showNewOrder && (
        <NewOrder onDismiss={() => setShowNewOrder(false)} refresh />
      )}
    </div>
  )
}
Example #15
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
ManageGiftCard: React.FC<RouteComponentProps> = () => {
  const { products } = useAdminProducts(
    {
      is_giftcard: "true",
    },
    {
      keepPreviousData: true,
    }
  )

  const giftCard = products?.[0]

  const notification = useNotification()
  const updateGiftCard = useAdminUpdateProduct(giftCard?.id!)
  const [submitting, setSubmitting] = useState(false)

  const onSubmit = async (data) => {
    setSubmitting(true)
    const images = data.images
      .filter((img) => img.url.startsWith("blob"))
      .map((img) => img.nativeFile)

    let uploadedImgs = []
    if (images.length > 0) {
      uploadedImgs = await Medusa.uploads
        .create(images)
        .then(({ data }) => {
          const uploaded = data.uploads.map(({ url }) => url)
          return uploaded
        })
        .catch((err) => {
          setSubmitting(false)
          notification("Error uploading images", getErrorMessage(err), "error")
          return
        })
    }

    const newData = {
      ...data,
      images: consolidateImages(data.images, uploadedImgs),
    }

    updateGiftCard.mutate(formValuesToUpdateGiftCardMapper(newData), {
      onSuccess: () => {
        setSubmitting(false)
        notification("Success", "Product updated successfully", "success")
      },
      onError: (error) => {
        setSubmitting(false)
        notification("Error", getErrorMessage(error), "error")
      },
    })
  }

  if (!giftCard) {
    return (
      <div className="w-full h-screen flex items-center justify-center">
        <Spinner variant="secondary" size="large" />
      </div>
    )
  }

  return (
    <GiftCardFormProvider
      giftCard={giftCardToFormValuesMapper(giftCard)}
      onSubmit={onSubmit}
    >
      <div className="flex flex-col gap-y-large pb-xlarge">
        <Information giftCard={giftCard} />
        <Denominations giftCard={giftCard} />
        <Images />
      </div>
      <UpdateNotification isLoading={submitting} />
    </GiftCardFormProvider>
  )
}
Example #16
Source File: new.tsx    From admin with MIT License 5 votes vote down vote up
New: React.FC<RouteComponentProps> = () => {
  return (
    <PriceListFormProvider>
      <PriceListForm viewType={ViewType.CREATE} />
    </PriceListFormProvider>
  )
}
Example #17
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
Edit: React.FC<RouteComponentProps<{ id: string }>> = ({ id }) => {
  const { discount, isLoading } = useAdminDiscount(id!, undefined, {
    enabled: !!id,
  })
  const [showDelete, setShowDelete] = useState(false)
  const deleteDiscount = useAdminDeleteDiscount(id!)
  const notification = useNotification()

  const handleDelete = () => {
    deleteDiscount.mutate(undefined, {
      onSuccess: () => {
        notification("Success", "Discount deleted", "success")
      },
      onError: (error) => {
        notification("Error", getErrorMessage(error), "error")
      },
    })
  }

  return (
    <div className="pb-xlarge">
      {showDelete && (
        <DeletePrompt
          handleClose={() => setShowDelete(!showDelete)}
          onDelete={async () => handleDelete()}
          successText="Discount deleted"
          confirmText="Yes, delete"
          text="Are you sure you want to delete this discount?"
          heading="Delete discount"
        />
      )}

      <Breadcrumb
        currentPage="Add Discount"
        previousBreadcrumb="Discount"
        previousRoute="/a/discounts"
      />
      {isLoading || !discount ? (
        <div className="h-full flex items-center justify-center">
          <Spinner variant="secondary" />
        </div>
      ) : (
        <div className="flex flex-col gap-y-4">
          <General discount={discount} />
          <Configurations discount={discount} />
          <Conditions discount={discount} />
          <RawJSON data={discount} title="Raw discount" />
        </div>
      )}
    </div>
  )
}
Example #18
Source File: Assessment.tsx    From listo with MIT License 5 votes vote down vote up
Assessment = (_: RouteComponentProps) => <FormSteps />
Example #19
Source File: InstalledAppPage.tsx    From editor with MIT License 5 votes vote down vote up
InstalledAppPage = (_props: RouteComponentProps) => {
    return (
        <div className={"InstalledApp"}>
            <InstalledTextlintList url={location.href} />
        </div>
    );
}
Example #20
Source File: NotFound.tsx    From baleen3 with Apache License 2.0 5 votes vote down vote up
NotFound: React.FC<RouteComponentProps> = () => (
  <>
    <Header />
    <Page data-testid="NotFound">
      <Contents />
    </Page>
  </>
)
Example #21
Source File: Help.tsx    From baleen3 with Apache License 2.0 5 votes vote down vote up
Help: React.FC<RouteComponentProps> = () => (
  <>
    <Header />
    <Page data-testid="Help">
      <HelpContents />
    </Page>
  </>
)
Example #22
Source File: Components.tsx    From baleen3 with Apache License 2.0 5 votes vote down vote up
Components: React.FC<RouteComponentProps> = () => (
  <>
    <Header />
    <Page data-testid="Components">
      <ComponentsContainer />
    </Page>
  </>
)
Example #23
Source File: User.tsx    From office-booker with MIT License 4 votes vote down vote up
UserAdmin: React.FC<RouteComponentProps<{ email: string }>> = (props) => {
  // Global state
  const { state, dispatch } = useContext(AppContext);
  const { config, user } = state;
  const canEdit = user?.permissions.canEditUsers === true;

  // Local state
  const [loading, setLoading] = useState(true);
  const [offices, setOffices] = useState<Office[] | undefined>();
  const [selectedUser, setSelectedUser] = useState<User | undefined>();
  const [autoApprovedSelected, setAutoApprovedSelected] = useState(false);

  // Effects
  useEffect(() => {
    if (user && !user.permissions.canViewUsers) {
      // No permissions - Bounce to home page
      navigate('/');
    }
  }, [user]);

  useEffect(() => {
    if (user) {
      // Get selected user
      getUser(props.email || '')
        .then((selectedUser) => setSelectedUser(selectedUser))
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [user, props.email, dispatch]);

  useEffect(() => {
    if (user && selectedUser) {
      // Get all offices admin can manage
      setOffices(user.permissions.officesCanManageBookingsFor);

      if (config?.reasonToBookRequired && selectedUser.autoApproved !== undefined) {
        setAutoApprovedSelected(selectedUser.autoApproved);
      }
    }
  }, [user, selectedUser, dispatch, config?.reasonToBookRequired]);

  useEffect(() => {
    if (offices) {
      // Wait for global state to be ready
      setLoading(false);
    }
  }, [offices]);

  // Handlers
  const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    // Validate
    if (selectedUser === undefined) {
      return;
    }

    if (selectedUser.role.name === 'Office Admin' && selectedUser.role.offices.length === 0) {
      return dispatch({
        type: 'SET_ALERT',
        payload: {
          message: 'Please select at least one office',
          color: 'error',
        },
      });
    }

    // Create/update user
    const role = selectedUser.role.name === 'System Admin' ? undefined : selectedUser.role;

    const putBody = config?.reasonToBookRequired
      ? {
          email: selectedUser.email,
          quota: selectedUser.quota,
          role,
          autoApproved: selectedUser.autoApproved,
        }
      : {
          email: selectedUser.email,
          quota: selectedUser.quota,
          role,
        };

    putUser(putBody)
      .then((updatedUser) => {
        // Update local state
        setSelectedUser(updatedUser);

        // Confirmation alert
        dispatch({
          type: 'SET_ALERT',
          payload: {
            message: `${updatedUser.email} updated`,
            color: 'success',
          },
        });
      })
      .catch((err) => {
        // Handle errors
        dispatch({
          type: 'SET_ALERT',
          payload: {
            message: formatError(err),
            color: 'error',
          },
        });
      });
  };

  // Render
  if (!user) {
    return null;
  }

  return (
    <AdminLayout currentRoute="users">
      <UserStyles>
        {loading || !selectedUser || !offices ? (
          <Loading />
        ) : (
          <>
            <h3>Users</h3>

            <Paper square className="form-container">
              <h4>Edit user</h4>
              <h5>{selectedUser.email}</h5>

              <form onSubmit={handleFormSubmit}>
                <div className="field">
                  <FormControl variant="outlined" className="input">
                    <InputLabel id="role-label" shrink>
                      Role
                    </InputLabel>
                    <Select
                      labelId="role-label"
                      id="role"
                      value={selectedUser.role.name}
                      disabled={selectedUser.role.name === 'System Admin' || !canEdit}
                      onChange={(e) => {
                        const { value } = e.target;

                        setSelectedUser((selectedUser) => {
                          if (selectedUser === undefined) {
                            return;
                          }

                          if (value === 'Default') {
                            return { ...selectedUser, role: { name: 'Default' } };
                          }

                          if (value === 'Office Admin') {
                            return {
                              ...selectedUser,
                              role: { name: 'Office Admin', offices: [] },
                            };
                          }

                          return selectedUser;
                        });
                      }}
                      label="Role"
                    >
                      <MenuItem value={'Default'}>Default</MenuItem>
                      <MenuItem value={'Office Admin'}>Office Admin</MenuItem>
                      <MenuItem value={'System Admin'} disabled>
                        System Admin
                      </MenuItem>
                    </Select>
                  </FormControl>
                </div>

                {selectedUser.role.name === 'Office Admin' && (
                  <div className="field">
                    <Autocomplete
                      multiple
                      disabled={!canEdit}
                      options={offices.map((o) => o.name)}
                      value={
                        selectedUser.role.name === 'Office Admin'
                          ? selectedUser.role.offices.map((office) => office.name)
                          : []
                      }
                      onChange={(_e, value) =>
                        setSelectedUser((selectedUser) => {
                          if (selectedUser === undefined) {
                            return;
                          }

                          return {
                            ...selectedUser,
                            role: {
                              name: 'Office Admin',
                              offices: offices.filter((office) => value.includes(office.name)),
                            },
                          };
                        })
                      }
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          variant="outlined"
                          label="Offices"
                          fullWidth={false}
                          className="input"
                        />
                      )}
                      renderTags={(selectedOffices, tagProps) =>
                        selectedOffices.map((office, index: number) => (
                          <Chip
                            variant="outlined"
                            key={index}
                            label={office}
                            {...tagProps({ index })}
                          />
                        ))
                      }
                    />
                  </div>
                )}

                <div className="field">
                  <TextField
                    type="number"
                    variant="outlined"
                    disabled={!canEdit}
                    label="Weekly quota"
                    value={selectedUser.quota}
                    onChange={(e) => {
                      // Between 0 and 7
                      const quota = Number.parseInt(e.target.value);

                      setSelectedUser(
                        (selectedUser) =>
                          selectedUser && {
                            ...selectedUser,
                            quota: quota >= 0 && quota <= 7 ? quota : quota > 7 ? 7 : 0,
                          }
                      );
                    }}
                    className="input"
                  />
                </div>

                {config?.reasonToBookRequired && (
                  <div className="field">
                    <FormControlLabel
                      control={
                        <Checkbox
                          checked={autoApprovedSelected}
                          onChange={(event) =>
                            setSelectedUser(
                              (selectedUser) =>
                                selectedUser && {
                                  ...selectedUser,
                                  autoApproved: event.target.checked,
                                }
                            )
                          }
                          name="checkedB"
                          color="primary"
                        />
                      }
                      label="Auto Approved"
                    />
                  </div>
                )}

                {canEdit && (
                  <div className="buttons">
                    <OurButton
                      type="submit"
                      color="primary"
                      variant="contained"
                      disabled={selectedUser.quota < 0}
                    >
                      Save
                    </OurButton>
                  </div>
                )}
              </form>
            </Paper>

            <section className="help">
              <h3>About Roles</h3>

              <h4>Default</h4>

              <ul>
                <li>Any user with a valid email address gets this role.</li>
                <li>Can manage their own bookings only.</li>
              </ul>

              <h4>System Admin</h4>

              <ul>
                <li>Must be configured in infrastructure.</li>
                <li>Can view and edit all bookings in the system.</li>
                <li>Can view and edit all users</li>
              </ul>

              <h4>Office Admin</h4>

              <ul>
                <li>Must be assigned by a System Admin.</li>
                <li>Can view and edit bookings for their assigned offices.</li>
                <li>Can view other users (but can&apos;t edit).</li>
              </ul>

              <p>A default quota is applied to all users regardless of role.</p>
            </section>
          </>
        )}
      </UserStyles>
    </AdminLayout>
  );
}
Example #24
Source File: InviteView.tsx    From Frontend with MIT License 4 votes vote down vote up
InviteView: React.FC<RouteComponentProps> = () => {
  const { connectionMade } = useAnalytics();
  const { uid }: params = useParams();
  const location = useLocation();
  const toast = useToast();
  const intl = useIntl();
  const { profile } = useAuth();
  const [value, loading] = useObjectVal<Profile>(
    firebase.database().ref(`profiles/${uid}`)
  );
  const [
    createKnowsMutation,
    { loading: isLoadingConnection }
  ] = useCreateKnowsMutation({
    onCompleted() {
      connectionMade();
      toast({
        position: 'bottom-right',
        title: intl.formatMessage({ id: 'InviteView.Connected' }),
        description: intl.formatMessage(
          {
            id: 'InviteView.Connected-Description'
          },
          {
            name: value.displayName
          }
        ),
        status: 'success',
        isClosable: true
      });
    }
  });

  if (loading) {
    return <Spinner />;
  }

  const displayName = value && value.displayName ? value.displayName : 'user';
  const photoURL = value && value.photoURL ? value.photoURL : null;
  const shouldShowConnectButton = profile?.uid !== uid;

  return (
    <>
      <PageHeader
        heading={intl.formatMessage({ id: 'InviteView.heading' })}
        lead={intl.formatMessage(
          {
            id: 'InviteView.lead'
          },
          {
            name: value.displayName
          }
        )}
      />

      <AvatarGroup size="xl" max={2} mb={12}>
        <Avatar name={displayName} src={photoURL} />
        <Avatar bg="none" name="Contact Tracing" src={icon} />
      </AvatarGroup>
      {shouldShowConnectButton && (
        <Button
          isLoading={isLoadingConnection}
          width="200px"
          mb={16}
          variantColor="teal"
          onClick={() => {
            if (!profile) {
              navigate(`/me/sign-in?next=${location.pathname}`);
              return;
            }

            createKnowsMutation({
              variables: {
                fromUid: profile?.uid,
                toUid: uid
              }
            });
          }}
        >
          <FormattedMessage id="InviteView.Connect-button" />
        </Button>
      )}
      <Heading as="h3" mb={2} size="lg">
        <FormattedMessage id="InviteView.why-use" />
      </Heading>
      <List styleType="disc">
        <ListItem>
          <FormattedMessage id="InviteView.why-1" />
        </ListItem>
        <ListItem>
          <FormattedMessage id="InviteView.why-2" />
        </ListItem>
        <ListItem>
          <FormattedMessage id="InviteView.why-3" />
        </ListItem>
      </List>
    </>
  );
}
Example #25
Source File: api.tsx    From css-to-js with MIT License 4 votes vote down vote up
API: React.FC<RouteComponentProps> = () => {
  const [CSStoJSValue, setCSS2JSValue] = useState("");
  const [JSToJSXValue, setJSToJSXValue] = useState("");

  useEffect(() => {
    fetch("https://css2js.dotenv.dev/api/css2js", {
      method: "POST",
      body: "display: block",
    })
      .then((rsp) => rsp.json())
      .then(setCSS2JSValue);
  }, []);

  useEffect(() => {
    fetch("https://css2js.dotenv.dev/api/js2jsx", {
      method: "POST",
      body: "{display: 'block'}",
    })
      .then((rsp) => rsp.json())
      .then(setJSToJSXValue);
  }, [JSToJSXValue]);
  return (
    <main className="App api">
      <Nav />
      <div style={{ textAlign: "center" }}>
        <Logo />
      </div>
      <h1>API</h1>
      <p>
        You can access the functions we use to transform the code from the
        website or make your own apps using our exposed functions API.
      </p>
      <p>We offer three different endpoints for now:</p>
      <ul>
        <li>
          CSS to JS at{" "}
          <span style={{ color: " white" }}>
            https://css2js.dotenv.dev/api/css2js
          </span>
        </li>
        <li>
          CSS to JSX Props at{" "}
          <span style={{ color: " white" }}>
            https://css2js.dotenv.dev/api/css2jsx
          </span>
        </li>
        <li>
          JS to JSX Props at{" "}
          <span style={{ color: " white" }}>
            https://css2js.dotenv.dev/api/js2jsx
          </span>
        </li>
      </ul>

      <h2>Transform CSS to JS</h2>
      <Code
        language="javascript"
        code={`
     const js = await fetch("https://css2js.dotenv.dev/api/css2js", {
        method: "POST",
        body: "display: block"
      }).then(rsp => rsp.json())

      console.log(js)
      `}
      ></Code>
      <div>{JSON.stringify(CSStoJSValue, null, 2)}</div>
      <h2>Transform CSS to JS</h2>
      <Code
        language="javascript"
        code={`
     const css = await fetch("https://css2js.dotenv.dev/api/js2jsx", {
        method: "POST",
        body: "{display: "block"}"
      }).then(rsp => rsp.json())

      console.log(css)
      `}
      ></Code>
      <div>{JSON.stringify(JSToJSXValue, null, 2)}</div>
    </main>
  );
}
Example #26
Source File: RequireLogin.tsx    From office-booker with MIT License 4 votes vote down vote up
RequireLogin: React.FC<RouteComponentProps> = (props) => {
  // Global state
  const { state, dispatch } = useContext(AppContext);

  // Local state
  const [loading, setLoading] = useState(true);
  const [view, setView] = useState<View>({ name: 'email' });

  // Effects
  useEffect(() => {
    // Restore session
    if (!state.user) {
      // Retrieve cognito session
      getAuthState()
        .then((username) => {
          // Not found
          if (!username) {
            setView({ name: 'email' });
            setLoading(false);

            return;
          }

          // Retrieve DB user
          getUserCached(username)
            .then((data) =>
              dispatch({
                type: 'SET_USER',
                payload: data,
              })
            )
            .catch((err) =>
              dispatch({
                type: 'SET_ALERT',
                payload: {
                  message: formatError(err),
                  color: 'error',
                },
              })
            );
        })
        .catch((err) =>
          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          })
        );
    } else {
      // Default view
      setView({ name: 'email' });
    }
  }, [state.user, dispatch]);

  // Effects
  useEffect(() => {
    // Finished loading once we have retrieve the user
    if (state.user) {
      setLoading(false);
    }
  }, [state.user]);

  // Loading
  if (loading) {
    return (
      <Layout>
        <LoadingSpinner />
      </Layout>
    );
  }

  // Logged in
  if (state.user) {
    return <>{props.children}</>;
  }

  // Login/Validation code
  return (
    <Layout>
      {view.name === 'email' ? (
        <EnterEmail onComplete={(user) => setView({ name: 'code', user })} />
      ) : view.name === 'code' ? (
        <EnterCode
          user={view.user}
          onCodeExpired={() => {
            setLoading(true);
            signIn(view.user.getUsername()).then((user) => {
              setLoading(false);
              setView({ name: 'code', user });
            });
          }}
        />
      ) : null}
    </Layout>
  );
}
Example #27
Source File: ViewBooking.tsx    From office-booker with MIT License 4 votes vote down vote up
ViewBooking: React.FC<RouteComponentProps<Props>> = (props) => {
  // Global state
  const { state, dispatch } = useContext(AppContext);
  const { user } = state;

  // Local state
  const [loading, setLoading] = useState(true);
  const [booking, setBooking] = useState<Booking | undefined>(undefined);

  // Effects
  useEffect(() => {
    if (user) {
      getBookings({ user: user.email })
        .then((data) => {
          const findBooking = data.find((b) => b.id === props.id);

          if (findBooking) {
            setBooking(findBooking);
          } else {
            setLoading(false);

            // Bounce back to home
            setTimeout(() => navigate('/'), 2500);
          }
        })
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [dispatch, user, props.id]);

  useEffect(() => {
    // Finished loading
    if (booking) {
      setLoading(false);
    }
  }, [booking]);

  // Render
  if (!user) {
    return null;
  }

  const emailSplit = user.email.split('@');

  return (
    <Layout>
      {loading ? (
        <LoadingSpinner />
      ) : (
        <ViewBookingStyles>
          {booking ? (
            <Paper square className="card">
              <p className="day">
                {format(
                  parse(booking.date, 'y-MM-dd', new Date(), DATE_FNS_OPTIONS),
                  'eeee',
                  DATE_FNS_OPTIONS
                )}
              </p>
              <h2>
                {format(
                  parse(booking.date, 'y-MM-dd', new Date(), DATE_FNS_OPTIONS),
                  'do LLLL',
                  DATE_FNS_OPTIONS
                )}
              </h2>

              <h3>{booking.office.name}</h3>
              {booking.parking && <p className="parking">+ parking</p>}

              <div className="breaker"></div>

              <h4>{emailSplit[0]}</h4>
              <p className="domain">@{emailSplit[1]}</p>
            </Paper>
          ) : (
            <p className="not-found">
              Sorry, we can&apos;t find your booking reference. <br />
              Redirecting you to home...
            </p>
          )}

          <div className="button">
            <OurButton
              type="submit"
              variant="contained"
              color="primary"
              onClick={() => {
                navigate(`/`);
              }}
            >
              Home
            </OurButton>
          </div>
        </ViewBookingStyles>
      )}
    </Layout>
  );
}
Example #28
Source File: UpcomingBookings.tsx    From office-booker with MIT License 4 votes vote down vote up
UpcomingBookings: React.FC<RouteComponentProps> = () => {
  // Global state
  const { state, dispatch } = useContext(AppContext);

  // Local state
  const [loading, setLoading] = useState(true);
  const [upcomingBookings, setUpcomingBookings] = useState<Booking[] | undefined>();
  const [previousBookings, setPreviousBookings] = useState<Booking[] | undefined>();

  // Effects
  useEffect(() => {
    if (state.user) {
      getBookings({ user: state.user.email })
        .then((data) => {
          // Split for previous and upcoming
          const today = format(startOfDay(new Date()), 'yyyy-MM-dd');

          setUpcomingBookings(data.filter((b) => b.date >= today));
          setPreviousBookings(data.filter((b) => b.date < today));
        })
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [state.user, dispatch]);

  useEffect(() => {
    // Find booking
    if (upcomingBookings && previousBookings) {
      setLoading(false);
    }
  }, [upcomingBookings, previousBookings]);

  // Render
  return (
    <Layout>
      {loading ? (
        <LoadingSpinner />
      ) : (
        <UpcomingBookingsStyles>
          <h2>Upcoming Bookings</h2>

          {upcomingBookings && upcomingBookings.length > 0 ? (
            <Paper square className="bookings">
              {upcomingBookings.map((row, index) => (
                <div key={row.id} className="grid">
                  <div key={index} className="row">
                    <div className="left">
                      <p className="date">
                        {format(
                          parse(row.date, 'y-MM-dd', new Date(), DATE_FNS_OPTIONS),
                          'do LLL',
                          DATE_FNS_OPTIONS
                        )}
                      </p>
                      <p className="office">{row.office.name}</p>
                    </div>
                    <div className="right">
                      <OurButton
                        size="small"
                        variant="contained"
                        color="primary"
                        onClick={() => {
                          navigate(`./booking/${row?.id}`);
                        }}
                        endIcon={row.parking ? <EmojiTransportationIcon /> : <BusinessIcon />}
                      >
                        View Pass
                      </OurButton>
                    </div>
                  </div>
                </div>
              ))}
            </Paper>
          ) : (
            <p>No upcoming bookings found.</p>
          )}

          {previousBookings && previousBookings.length > 0 && (
            <>
              <h3>Previous Bookings</h3>

              <ul>
                {previousBookings.map((row) => (
                  <li key={row.id}>
                    {format(
                      parse(row.date, 'yyyy-MM-dd', new Date(), DATE_FNS_OPTIONS),
                      'do LLLL',
                      DATE_FNS_OPTIONS
                    )}
                    {` `}
                    <span>at {row.office.name}</span>
                    {` `}
                    <span>{row.parking ? '(+ Parking)' : ''}</span>
                  </li>
                ))}
              </ul>
            </>
          )}

          <div className="button">
            <OurButton
              type="button"
              variant="contained"
              color="primary"
              onClick={() => {
                navigate(`/`);
              }}
            >
              Home
            </OurButton>
          </div>
        </UpcomingBookingsStyles>
      )}
    </Layout>
  );
}
Example #29
Source File: Privacy.tsx    From office-booker with MIT License 4 votes vote down vote up
Privacy: React.FC<RouteComponentProps> = () => (
  <Layout>
    <HelpStyles>
      <h3>Privacy Policy</h3>
      <p>
        Office Booker is operated by Our Company. This privacy policy will explain how we use the
        personal data we collect from you when you use our website.
      </p>
      <p>Topics:</p>
      <ul>
        <li>What data do we collect?</li>
        <li>How do we collect your data?</li>
        <li>How will we use your data?</li>
        <li>How do we store your data?</li>
        <li>Marketing</li>
        <li>What are your data protection rights?</li>
        <li>What are cookies?</li>
        <li>How do we use cookies?</li>
        <li>What types of cookies do we use?</li>
        <li>How to manage your cookies</li>
        <li>Privacy policies of other websites</li>
        <li>Changes to our privacy policy</li>
        <li>How to contact us</li>
        <li>How to contact the appropriate authorities</li>
      </ul>
      <h3>What data do we collect?</h3>
      <p>Our Company collects the following data:</p>
      <ul>
        <li>Authorisation information (your email address)</li>
        <li>Booking records (including your email address)</li>
        <li>Audit logs (containing every booking created or deleted)</li>
        <li>Access logs (including your email address)</li>
      </ul>
      <h3>How do we collect your data?</h3>
      <p>
        You directly provide Our Company with most of the data we collect. We collect data and
        process data when you:
      </p>
      <ul>
        <li>Log into the website.</li>
        <li>Make a booking to visit an office.</li>
        <li>Use or view our website.</li>
      </ul>
      <h3>How will we use your data?</h3>
      <p>Our Company collects your data so that we can:</p>
      <ul>
        <li>Verify you are an employee of Our Company.</li>
        <li>Verify you have approval to access a specific office on a specific day.</li>
        <li>Monitor the system for data corruption, unauthorised access or abuse.</li>
      </ul>
      <h3>How do we store your data?</h3>
      <p>Our Company securely stores your data on Amazon Web Services.</p>
      <p>
        Our Company permanently deletes all audit logs, access logs and bookings after after a
        maximum of 30 days.
      </p>
      <p>
        Our Company will keep your user profile (containing your email address) for the lifetime of
        the system to allow you to log back in. You can request your email address to be removed
        from the system by emailing [email protected]
      </p>
      <h3>Marketing</h3>
      <p>We will not use your email address for any marketing purposes.</p>
      <h3>What are your data protection rights?</h3>
      <p>
        Our Company would like to make sure you are fully aware of all of your data protection
        rights. Every user is entitled to the following:
      </p>
      <p>
        <strong>The right to access</strong>&nbsp;&ndash; You have the right to request Our Company
        for copies of your personal data. We may charge you a small fee for this service.
      </p>
      <p>
        <strong>The right to rectification</strong>&nbsp;&ndash; You have the right to request that
        Our Company correct any information you believe is inaccurate. You also have the right to
        request Our Company to complete the information you believe is incomplete.
      </p>
      <p>
        <strong>The right to erasure</strong>&nbsp;&ndash; You have the right to request that Our
        Company erase your personal data, under certain conditions.
      </p>
      <p>
        <strong>The right to restrict processing</strong>&nbsp;&ndash; You have the right to request
        that Our Company restrict the processing of your personal data, under certain conditions.
      </p>
      <p>
        <strong>The right to object to processing</strong>&nbsp;&ndash; You have the right to object
        to Our Company&rsquo;s processing of your personal data, under certain conditions.
      </p>
      <p>
        <strong>The right to data portability</strong>&nbsp;&ndash; You have the right to request
        that Our Company transfer the data that we have collected to another organization, or
        directly to you, under certain conditions.
      </p>
      <p>
        If you make a request, we have one month to respond to you. If you would like to exercise
        any of these rights, please contact us at our email: [email protected]
      </p>
      {/* <h3>Cookies</h3>
      <p>
        Cookies are text files placed on your computer to collect standard Internet log information
        and visitor behavior information. When you visit our websites, we may collect information
        from you automatically through cookies or similar technology
      </p>
      <p>For further information, visit allaboutcookies.org.</p>
      <h3>How do we use cookies?</h3>
      <p>
        Our Company uses cookies in a range of ways to improve your experience on our website,
        including:
      </p>
      <ul>
        <li>Keeping you signed in</li>
        <li>Understanding how you use our website</li>
        <li>[Add any uses your company has for cookies]</li>
      </ul>
      <h3>What types of cookies do we use?</h3>
      <p>There are a number of different types of cookies, however, our website uses:</p>
      <ul>
        <li>
          Functionality &ndash; Our Company uses these cookies so that we recognize you on our
          website and remember your previously selected preferences. These could include what
          language you prefer and location you are in. A mix of first-party and third-party cookies
          are used.
        </li>
        <li>
          Advertising &ndash; Our Company uses these cookies to collect information about your visit
          to our website, the content you viewed, the links you followed and information about your
          browser, device, and your IP address. Our Company sometimes shares some limited aspects of
          this data with third parties for advertising purposes. We may also share online data
          collected through cookies with our advertising partners. This means that when you visit
          another website, you may be shown advertising based on your browsing patterns on our
          website.
        </li>
        <li>[Add any other types of cookies your company uses]</li>
      </ul>
      <h3>How to manage cookies</h3>
      <p>
        You can set your browser not to accept cookies, and the above website tells you how to
        remove cookies from your browser. However, in a few cases, some of our website features may
        not function as a result.
      </p> */}
      <h3>Privacy policies of other websites</h3>
      <p>
        The Office Booker website contains links to other websites. Our privacy policy applies only
        to our website, so if you click on a link to another website, you should read their privacy
        policy.
      </p>
      <h3>Changes to our privacy policy</h3>
      <p>
        Our Company keeps its privacy policy under regular review and places any updates on this web
        page. This privacy policy was last updated on 1 July 2020.
      </p>
      <h3>How to contact us</h3>
      <p>
        If you have any questions about Our Company&rsquo;s privacy policy, the data we hold on you,
        or you would like to exercise one of your data protection rights, please do not hesitate to
        contact us.
      </p>
      <p>Email us at: [email protected]</p>
      <h3>How to contact the appropriate authority</h3>
      <p>
        Should you wish to report a complaint or if you feel that Our Company has not addressed your
        concern in a satisfactory manner, you may contact the Information Commissioner&rsquo;s
        Office.
      </p>
      <p>Email: [email protected]</p>
    </HelpStyles>
  </Layout>
)