@apollo/client#useMutation JavaScript Examples

The following examples show how to use @apollo/client#useMutation. 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: Product.js    From ReactNativeApolloOnlineStore with MIT License 6 votes vote down vote up
export function Product({product, onPress}) {
  const [addOrRemoveProductFromFavorite] = useMutation(
    ADD_OR_REMOVE_PRODUCT_FROM_FAVORITE,
    {
      variables: {
        productId: product.id,
      },
    },
  );

  return (
    <Card key={product.id} style={styles.card} onPress={onPress}>
      <Image
        style={styles.thumb}
        source={{uri: BASE_URL + product.thumb.url}}
      />
      <View style={styles.infoContainer}>
        <Text style={styles.name}>{product.name}</Text>
        <Text style={styles.price}>{product.price}</Text>
        <Text style={styles.description}>{product.description}</Text>
      </View>
      <FavoriteIcon
        favorite={product.favorite}
        onPress={async () => {
          await addOrRemoveProductFromFavorite();
        }}
      />
    </Card>
  );
}
Example #2
Source File: metrics.js    From graphql-sample-apps with Apache License 2.0 6 votes vote down vote up
Metrics = () => {
  const {loading, error, data} = useQuery(query);
  const [newMetricName, setNewMetricName] = useState("");
  const [addMetric, { loading: mutationLoading }] = useMutation(addMetricMutation, {
    awaitRefetchQueries: true,
    refetchQueries: [{query}],
  });

  const metrics = data?.queryMetric || []

  return <>
    <Navbar title="Metrics" color="primary" />
    <Content>
      {loading && <Backdrop open={loading || mutationLoading} >
        <CircularProgress />
      </Backdrop>}
      {error && <Alert severity="error">Something Went Horribly Wrong</Alert>}
      <Card style={{ padding: 30 }}>
        <Typography>Here are the metrics currently configured:</Typography>
        <List>
          {metrics.map(({ name }, index) => <ListItem item key={index} sm={12} md={6} lg={3}>
            <Typography>{name}</Typography>
          </ListItem>)}
        </List>

        <TextField
          label="Add Metric"
          defaultValue={newMetricName}
          onChange={e => setNewMetricName(e.target.value)}
        />
        <UglyButton onClick={() => addMetric({ variables: { newMetricName } })} disabled={newMetricName === ""}>
          Add Metric
        </UglyButton>
      </Card>
    </Content>
  </>
}
Example #3
Source File: index.js    From realworld with MIT License 6 votes vote down vote up
function RegisterPage() {
  const router = useRouter();
  const [signUp] = useMutation(RegisterPageSignUpMutation);

  return (
    <Layout>
      <div className="auth-page">
        <RegisterForm
          onSubmit={(values, { setSubmitting, setStatus }) => {
            signUp({ variables: values })
              .then(() => {
                router.push('/login', '/login');
              })
              .catch(err => {
                handleValidationError(err, setStatus);
                console.error(err);
                setSubmitting(false);
              });
          }}
        />
      </div>
    </Layout>
  );
}
Example #4
Source File: Podcast.js    From grandcast.fm with Apache License 2.0 6 votes vote down vote up
Podcast = ({ podcast }) => {
  const { title, itunesId, description, artwork, categories } = podcast
  const [subscribeMutation, { data }] = useMutation(PODCAST_SUBSCRIBE)
  return (
    <Flex rounded="lg" borderWidth="2px" m={4}>
      <Box width="200px">
        <Image src={artwork} boxSize="200px" />
        <Button
          width="100%"
          onClick={() =>
            subscribeMutation({ variables: { itunesID: itunesId } })
          }
        >
          <AddIcon />
        </Button>
      </Box>
      <Box m={4} maxWidth="300px">
        <Heading noOfLines={2}>{title}</Heading>
        <Text noOfLines={3}>{description}</Text>
        <Stack isInline>
          {categories.slice(0, 3).map((c) => {
            return <Tag key={c}>{c}</Tag>
          })}
        </Stack>
      </Box>
    </Flex>
  )
}
Example #5
Source File: use-wishlist.js    From horondi_client_fe with MIT License 6 votes vote down vote up
useWishlist = () => {
  const dispatch = useDispatch();
  const [wishlist, setWishlist] = useState(getFromLocalStorage(WISHLIST_KEY));
  const [addProductMutation] = useMutation(addProductToWishlist);
  const [deleteProductMutation] = useMutation(deleteProductFromWishlist);

  useEffect(() => {
    setToLocalStorage(WISHLIST_KEY, wishlist);
    dispatch(setNewWishlist(wishlist));
  }, [wishlist, dispatch]);

  const isInWishlist = (product) =>
    wishlist.find((wishlistItem) => wishlistItem._id === product._id);

  const addToWishlist = (item) => {
    setWishlist((prevWishlist) => [...prevWishlist, item]);
    setToLocalStorage(WISHLIST_KEY, wishlist);
    addProductMutation({ variables: { productId: item._id } });
  };

  const removeFromWishlist = (item) => {
    setWishlist((prevWishlist) =>
      prevWishlist.filter((wishlistItem) => wishlistItem._id !== item._id)
    );
    setToLocalStorage(WISHLIST_KEY, wishlist);
    deleteProductMutation({ variables: { productId: item._id } });
  };

  const wishlistOperations = {
    addToWishlist,
    removeFromWishlist
  };

  return { isInWishlist, wishlist, wishlistOperations };
}
Example #6
Source File: index.js    From realworld with MIT License 6 votes vote down vote up
function LoginPage() {
  const [signIn] = useMutation(LoginPageSignInMutation);

  return (
    <Layout>
      <div className="auth-page">
        <LoginForm
          onSubmit={(values, { setSubmitting, setStatus }) => {
            signIn({
              variables: values,
            })
              .then(res => {
                document.cookie = cookie.serialize(
                  'authorization',
                  `Bearer ${res.data.signIn.token}`,
                  {
                    maxAge: 60 * 60 * 24,
                    path: '/',
                    sameSite: 'lax',
                    secure: process.env.NODE_ENV === 'production',
                  }
                );
                window.location.assign('/');
              })
              .catch(err => {
                handleValidationError(err, setStatus);
                console.error(err);
                setSubmitting(false);
              });
          }}
        />
      </div>
    </Layout>
  );
}
Example #7
Source File: lightning-auth.js    From stacker.news with MIT License 6 votes vote down vote up
export function LightningAuth ({ callbackUrl }) {
  // query for challenge
  const [createAuth, { data, error }] = useMutation(gql`
    mutation createAuth {
      createAuth {
        k1
        encodedUrl
      }
    }`)

  useEffect(createAuth, [])

  if (error) return <div>error</div>

  if (!data) {
    return <LnQRSkeleton status='generating' />
  }

  return <LnQRAuth {...data.createAuth} callbackUrl={callbackUrl} />
}
Example #8
Source File: index.js    From realworld with MIT License 6 votes vote down vote up
function EditorPage() {
  const router = useRouter();
  const page = useQuery(EditorPageQuery, {
    onCompleted: useCallback(
      data => {
        if (data.viewer?.canCreateArticle.value) return;

        router.replace(router.asPath, '/', { shallow: true });
      },
      [router]
    ),
  });
  const [createArticle] = useMutation(EditorPageCreateArticleMutation);

  if (page.networkStatus === NetworkStatus.loading) return null;

  return (
    <Layout {...page.data.viewer}>
      <div className="editor-page">
        <ArticleForm
          onSubmit={(values, { setSubmitting, setStatus }) => {
            createArticle({ variables: values })
              .then(res => {
                router.push(
                  '/article/[slug]',
                  `/article/${res.data.createArticle.article.slug}`
                );
              })
              .catch(err => {
                handleValidationError(err, setStatus);
                console.error(err);
                setSubmitting(false);
              });
          }}
        />
      </div>
    </Layout>
  );
}
Example #9
Source File: settings.js    From stacker.news with MIT License 6 votes vote down vote up
export function EmailLinkForm ({ callbackUrl }) {
  const [linkUnverifiedEmail] = useMutation(
    gql`
      mutation linkUnverifiedEmail($email: String!) {
        linkUnverifiedEmail(email: $email)
      }`
  )

  return (
    <Form
      initial={{
        email: ''
      }}
      schema={EmailSchema}
      onSubmit={async ({ email }) => {
        // add email to user's account
        // then call signIn
        const { data } = await linkUnverifiedEmail({ variables: { email } })
        if (data.linkUnverifiedEmail) {
          signIn('email', { email, callbackUrl })
        }
      }}
    >
      <div className='d-flex align-items-center'>
        <Input
          name='email'
          placeholder='[email protected]'
          required
          groupClassName='mb-0'
        />
        <SubmitButton className='ml-2' variant='secondary'>Link Email</SubmitButton>
      </div>
    </Form>
  )
}
Example #10
Source File: promo-code-edit.js    From horondi_admin with MIT License 6 votes vote down vote up
function PromoCodeEdit() {
  const { id } = useParams();
  const history = useHistory();
  const dispatch = useDispatch();

  const { loading, error, data } = useQuery(getPromoCodeById, {
    variables: { id },
    fetchPolicy: 'no-cache'
  });

  const onCompletedHandler = () => {
    dispatch(showSuccessSnackbar('Успішно змінено'));
  };

  const [updatePromoCodeHandler] = useMutation(updatePromoCode, {
    onCompleted: onCompletedHandler
  });

  const pathToPromoCodesPage = config.routes.pathToPromoCodes;

  const goToPromoPage = () => {
    history.push(pathToPromoCodesPage);
  };

  if (loading || error) {
    return <LoadingBar />;
  }

  return (
    <PromoCodeForm
      initialState={data.getPromoCodeById}
      promoValidationSchema={promoValidationSchema}
      pathToPromoCodesPage={pathToPromoCodesPage}
      addPromoCodeHandler={updatePromoCodeHandler}
      goToPromoPage={goToPromoPage}
    />
  );
}
Example #11
Source File: signout.js    From next-ecommerce with MIT License 6 votes vote down vote up
function SignOut() {
  const client = useApolloClient();
  const router = useRouter();
  const [signOut] = useMutation(SignOutMutation);

  useEffect(() => {
    signOut().then(() => {
      client.resetStore().then(() => {
        router.push('/user/login');
      });
    });
  }, [signOut, router, client]);

  return <p>Signing out...</p>;
}
Example #12
Source File: promo-code-add.js    From horondi_admin with MIT License 6 votes vote down vote up
PromoCodeAdd = () => {
  const history = useHistory();
  const dispatch = useDispatch();

  const token = getFromLocalStorage(LOCAL_STORAGE.AUTH_ACCESS_TOKEN);
  const pathToPromoCodesPage = config.routes.pathToPromoCodes;

  const onCompletedHandler = () => {
    dispatch(showSuccessSnackbar('Успішно додано'));
  };

  const [addPromoCodeHandler] = useMutation(addPromoCodes, {
    onCompleted: onCompletedHandler,
    context: {
      headers: {
        token
      }
    }
  });

  const goToPromoPage = () => {
    history.push(pathToPromoCodesPage);
  };

  return (
    <PromoCodeForm
      promoValidationSchema={promoValidationSchema}
      pathToPromoCodesPage={pathToPromoCodesPage}
      goToPromoPage={goToPromoPage}
      addPromoCodeHandler={addPromoCodeHandler}
    />
  );
}
Example #13
Source File: wallet.js    From stacker.news with MIT License 6 votes vote down vote up
export function LnWithdrawal () {
  // query for challenge
  const [createAuth, { data, error }] = useMutation(gql`
    mutation createAuth {
      createWith {
        k1
        encodedUrl
      }
    }`)

  useEffect(createAuth, [])

  if (error) return <div>error</div>

  if (!data) {
    return <LnQRSkeleton status='generating' />
  }

  return <LnQRWith {...data.createWith} />
}
Example #14
Source File: AuthProvider.js    From gatsby-apollo-wpgraphql-jwt-starter with MIT License 6 votes vote down vote up
AuthProvider = ({ children }) => {
  const [loginUser, { data: loginData }] = useMutation(LOGIN_USER)
  const [userData, setUserData] = useState(null)

  const providerValue = useMemo(() => (
    {
      loginUser: ({ username, password }) => loginUser({
        variables: {
          input: {
            clientMutationId: uuid(),
            username: username,
            password: password,
          },
        },
      }).then((response) => {
        console.log("Response", response)
        // console.log("Data", data)
        const { login } = response.data
        const user = (login && login.user) ? login.user : {}

        setRefreshToken(user, () => navigate("/dashboard/"))
      }),
      loginData: loginData,
      userData: userData,
      setUserData: setUserData
    }
  ), [loginUser, loginData, userData, setUserData])


  return (
    <AuthContext.Provider value={providerValue}>
      {children}
    </AuthContext.Provider>
  )
}
Example #15
Source File: index.js    From realworld with MIT License 5 votes vote down vote up
function EditorUpdatePage() {
  const router = useRouter();
  const skip = !router.query.slug;
  const page = useQuery(EditorUpdatePageQuery, {
    onCompleted: useCallback(
      data => {
        if (data.article.canUpdate.value) return;

        router.replace(router.asPath, '/', { shallow: true });
      },
      [router]
    ),
    skip,
    variables: queryToVariables(router.query),
  });

  const [updateArticle] = useMutation(EditorUpdatePageUpdateArticleMutation);

  if (page.networkStatus === NetworkStatus.loading || skip) return null;

  return (
    <Layout {...page.data.viewer}>
      <div className="editor-page">
        <ArticleForm
          onSubmit={(values, { setSubmitting, setStatus }) => {
            updateArticle({ variables: values })
              .then(res => {
                router.push(
                  '/article/[slug]',
                  `/article/${res.data.updateArticle.article.slug}`
                );
              })
              .catch(err => {
                handleValidationError(err, setStatus);
                console.error(err);
                setSubmitting(false);
              });
          }}
          {...page.data.article}
        />
      </div>
    </Layout>
  );
}
Example #16
Source File: material-about.js    From horondi_admin with MIT License 5 votes vote down vote up
MaterialAbout = ({ currentType }) => {
  const styles = useStyles();
  const common = useCommonStyles();
  const dispatch = useDispatch();
  const { data, refetch, loading } = useQuery(GET_MATERIALS_BLOCKS_BY_TYPE, {
    variables: {
      type: currentType,
      skip: 0,
      limit: 0
    }
  });

  const [deleteMaterialsBlockByIDMutation] = useMutation(
    DELETE_MATERIALS_BLOCK
  );

  const materialsData = data?.getMaterialsBlocksByType || {};
  const runRefetchData = () => refetch();

  useEffect(runRefetchData, [data]);

  const { openSuccessSnackbar } = useSuccessSnackbar();

  const completeDeleteHandler = (materialID) => {
    deleteMaterialsBlockByIDMutation({
      variables: {
        id: materialID
      }
    }).then(runRefetchData);
    dispatch(closeDialog());
  };

  const openDeleteModalHandler = (materialID) =>
    openSuccessSnackbar(() => completeDeleteHandler(materialID));

  const aboutMaterialItems = materialsData.items
    ? materialsData.items.map(({ _id, title, text, image }) => (
        <TableContainerRow
          image={image}
          key={_id}
          title={title}
          text={text[0].value}
          deleteHandler={() => openDeleteModalHandler(_id)}
          editHandler={() => null}
        />
      ))
    : null;

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

  return (
    <div className={common.container}>
      <div className={styles.header}>
        <Typography
          variant='h1'
          className={styles.materialTitle}
          data-cy='mainHeader'
        >
          {config.titles.materialTitles.mainPageTitle}
        </Typography>
        <Button
          data-test-id='createMaterialButton'
          id='addMaterials'
          component={Link}
          variant='contained'
          color='primary'
        >
          {CREATE_MATERIAL_TITLE_BLOCK}
        </Button>
      </div>
      <TableContainerGenerator
        id='AboutMaterialsTable'
        tableTitles={tableTitles}
        tableItems={aboutMaterialItems}
      />
    </div>
  );
}
Example #17
Source File: reply-form.test.js    From horondi_client_fe with MIT License 5 votes vote down vote up
useMutation.mockImplementation((query, options) => {
  options.onCompleted();
  options.onError();
  return [mockAddReply, { loading: false }];
});
Example #18
Source File: LoginForm.js    From gatsby-apollo-wpgraphql-jwt-starter with MIT License 5 votes vote down vote up
LoginForm = () => {
  const auth = useAuth();

  useEffect(() => {

    if (auth.isLoggedIn()) {
      navigate(`/dashboard/`, {replace: true})
    }
  }, [auth])

  const [loginUser, { data: loginData }] = useMutation(LOGIN_USER)

  const [fields, handleFieldChange] = useFormFields({
    username: "",
    password: "",
  })

  const handleSubmit = (e) => {
    e.preventDefault()

    loginUser({
      variables: {
        input: {
          clientMutationId: uuid(),
          username: fields.username,
          password: fields.password,
        },
      },
    }).then((response) => {
      // console.log("Response", response)
      const { login } = response.data

      if(login) {
        setAuthToken(login.authToken)
        setRefreshToken(login.refreshToken, () => navigate("/dashboard/"))
      }
    })
  }

  return (
    <form method="post" style={{ display: "flex", flexDirection: "column", alignItems: "flex-start" }}
          onSubmit={handleSubmit}>
      <div style={{display: "flex", flexDirection: "column"}}>
        <label htmlFor="username" style={labelStyle}><b>Email</b></label>
        <input onChange={handleFieldChange} value={fields.username} style={{ marginRight: 16 }} type="text"
               placeholder="Enter username" name="username" required/>

        <label htmlFor="password" style={labelStyle}><b>Password</b></label>
        <input onChange={handleFieldChange} value={fields.password} type="password" placeholder="Enter Password"
               name="password" required/>
      </div>

      <button style={{ margin: "16px 0" }} type="submit">Login</button>
    </form>
  )
}
Example #19
Source File: index.js    From realworld with MIT License 5 votes vote down vote up
function FeedPage() {
  const router = useRouter();

  const page = useQuery(FeedPageQuery, {
    onCompleted: useCallback(
      data => {
        if (data.viewer) return;

        router.replace(router.asPath, '/login', { shallow: true });
      },
      [router]
    ),
    notifyOnNetworkStatusChange: true,
    variables: queryToVariables(router.query),
  });

  const [favoriteArticle] = useMutation(FeedPageFavoriteArticleMutation);
  const [unfavoriteArticle] = useMutation(FeedPageUnfavoriteArticleMutation);

  if (page.networkStatus === NetworkStatus.loading) return null;

  return (
    <Layout {...page.data.viewer}>
      <div className="home-page">
        <HomePageBanner />
        <div className="container page">
          <div className="row">
            <div className="col-xs-12 col-md-9">
              <ViewerFeedToggle {...page.data.viewer} />
              {page.data.feedConnection.edges.map(edge => (
                <ArticlePreview
                  key={edge.node.slug}
                  onFavorite={favoriteArticle}
                  onUnfavorite={unfavoriteArticle}
                  {...edge.node}
                />
              ))}
              <Pagination {...page.data.feedConnection.pageInfo} />
            </div>
            <div className="col-xs-12 col-md-3">
              <Sidebar {...page.data} />
            </div>
          </div>
        </div>
      </div>
    </Layout>
  );
}
Example #20
Source File: index.js    From jamstack-ecommerce with MIT License 5 votes vote down vote up
export default function Home({data}) {

  const [createCheckoutMutaiton, {data:checkoutData}] = useMutation(createCheckout);
  const [addLineItemMuation, {data:addLineItemData}] = useMutation(addLineItem);


  useEffect(()=>{
    (async()=>{
      
      const response = await createCheckoutMutaiton({
        variables: {
          input: {}
        }
      });
      console.log("checkout session created ",response);
    
    })()
    


  },[])

  return (
    <div>
        <div>Hello Shopify Gatsby Apollo</div>
        <div>
          <button onClick={()=>{
            window.open(checkoutData.checkoutCreate.checkout.webUrl)
          }}>
            Checkout
          </button>
        </div>
        <div>
          {
            data.allShopifyProduct.edges.map(({node})=>(
              <div key={node.id} style={{border: "1px solid gray", borderRadius:"5px", margin:"10px", padding:"10px"}}>
                <div>
                  Name: {node.title}
                </div>
                <div>
                  Description: {node.description}
                </div>
                <div>
                  <img width="100px" src={node.images[0].originalSrc} />
                </div>
                <div>
                  Price: {node.variants[0].price}
                </div>
                <div>
                  <button onClick={async()=>{
                    console.log("add to cart clicked");

                    const responseAfterAdd = await addLineItemMuation({
                      variables:{
                        lineItems:[
                          {
                            quantity:1,
                            variantId: node.variants[0].id.split("__")[2]
                          }
                        ],
                        checkoutId: checkoutData.checkoutCreate.checkout.id
                      }
                    });
                    console.log("resposne after adding line item = ",responseAfterAdd);
                  }}>Add to Cart</button>
                </div>
              </div>
            ))
          }
        </div>
      </div>
  )
}
Example #21
Source File: comment-edit.js    From stacker.news with MIT License 5 votes vote down vote up
export default function CommentEdit ({ comment, editThreshold, onSuccess, onCancel }) {
  const [updateComment] = useMutation(
    gql`
      mutation updateComment($id: ID! $text: String!) {
        updateComment(id: $id, text: $text) {
          text
        }
      }`, {
      update (cache, { data: { updateComment } }) {
        cache.modify({
          id: `Item:${comment.id}`,
          fields: {
            text () {
              return updateComment.text
            }
          }
        })
      }
    }
  )

  return (
    <div className={`${styles.reply} mt-2`}>
      <Form
        initial={{
          text: comment.text
        }}
        schema={CommentSchema}
        onSubmit={async (values, { resetForm }) => {
          const { error } = await updateComment({ variables: { ...values, id: comment.id } })
          if (error) {
            throw new Error({ message: error.toString() })
          }
          if (onSuccess) {
            onSuccess()
          }
        }}
      >
        <MarkdownInput
          name='text'
          as={TextareaAutosize}
          minRows={6}
          autoFocus
          required
        />
        <SubmitButton variant='secondary' className='mt-1'>save</SubmitButton>
      </Form>
    </div>
  )
}
Example #22
Source File: AddComment.js    From ReactNativeApolloOnlineStore with MIT License 5 votes vote down vote up
export function AddComment({productId}) {
  const [comment, setComment] = React.useState('');
  const [createComment] = useMutation(CREATE_COMMENT, {
    update(cache, {data}) {
      const {comments} = cache.readQuery({
        query: GET_COMMENTS_BY_PRODUCT,
        variables: {
          productId,
        },
      });
      cache.writeQuery({
        query: GET_COMMENTS_BY_PRODUCT,
        variables: {
          productId,
        },
        data: {
          comments: [data.createComment.comment, ...comments],
        },
      });
    },
  });

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder={'Add Comment'}
        value={comment}
        onChangeText={setComment}
      />
      <TouchableOpacity
        style={styles.sendButton}
        disabled={!comment}
        onPress={async () => {
          await createComment({
            variables: {
              comment,
              productId,
            },
          });
          setComment('');
        }}>
        <Svg
          width={24}
          height={24}
          viewBox="0 0 24 24"
          fill="none"
          stroke="white"
          strokeWidth={2}
          strokeLinecap="round"
          strokeLinejoin="round">
          <Path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" />
        </Svg>
      </TouchableOpacity>
    </View>
  );
}
Example #23
Source File: Post.js    From graphql-sample-apps with Apache License 2.0 5 votes vote down vote up
Posts = () => {
  const [name, setName] = useState('');
  const [text, setText] = useState('');

  const [sendMessage, { error: mutationError }] = useMutation(SEND_MESSAGE);
  const { data, error: subscriptionError } = useSubscription(SUBSCRIPTION_QUERY);

  if (!data || !data.queryMessage) return (<h1>Connecting...</h1>);
  if (subscriptionError || mutationError) return (<h1>Error...</h1>);

  const handleClick = () => {
    if (name && text) {
      sendMessage({ variables: { name, text, time: (new Date()).toISOString() } });
    }
  }

  return (
    <>
      <hr></hr>
      <label>Enter you name : </label>
      <input required type="text" name="name" maxLength="25" onChange={e => setName(e.target.value)}></input>
      <label> Enter your message : </label>
      <input required type="text" name="message" onChange={e => setText(e.target.value)}></input>
      <button type="button" onClick={() => handleClick()}>Post</button>
      <hr></hr>
      <h3>Total Posts : {data.queryMessage.length}</h3>
      <hr></hr>
      <table>
        <thead>
          <tr>
            <th>Time</th>
            <th>Author</th>
            <th>Post</th>
          </tr>
        </thead>
        <tbody>
          {data.queryMessage.map(m => (
            <tr>
              <td>{(new Date(m.time)).toUTCString()}</td>
              <td align="left">{m.name}</td>
              <td width="1000" align="left">{m.text}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  );
}
Example #24
Source File: Forum.js    From ReactCookbook-source with MIT License 5 votes vote down vote up
Forum = () => {
  const {
    loading: messagesLoading,
    error: messagesError,
    data,
  } = useQuery(MESSAGES)
  const [addMessage] = useMutation(ADD_MESSAGE)
  const [text, setText] = useState()
  const [author, setAuthor] = useState()

  const messages = data && data.messages

  return (
    <div className="App">
      <input
        type="text"
        value={author}
        placeholder="Author"
        onChange={(evt) => setAuthor(evt.target.value)}
      />
      <textarea
        value={text}
        placeholder="Message"
        onChange={(evt) => setText(evt.target.value)}
      />
      <button
        onClick={async () => {
          try {
            await addMessage({
              variables: { author, text },
              refetchQueries: ['Messages'],
            })
            setText('')
            setAuthor('')
          } catch (err) {}
        }}
      >
        Post
      </button>
      {messagesError ? (
        <div className="error">
          Something went wrong:
          <div className="error-contents">
            {messagesError.message}
          </div>
        </div>
      ) : messagesLoading ? (
        <div className="loading">Loading...</div>
      ) : messages && messages.length ? (
        <dl>
          {messages.map((m) => (
            <>
              <dt>{m.author}</dt>
              <dd>{m.text}</dd>
            </>
          ))}
        </dl>
      ) : (
        'No messages'
      )}
    </div>
  )
}
Example #25
Source File: add-data.js    From graphql-sample-apps with Apache License 2.0 5 votes vote down vote up
AddData = ({currentTime = new Date()}) => {
  const {loading, error, data} = useQuery(query);
  const [date, setDate] = useState(currentTime.toISOString().substr(0, 10))
  const [values, setValues] = useState({})
  const [addCollectionMutation] = useMutation(addCollection);

  const metrics = data?.queryMetric || []

  const submitMetrics = async () => {
    const readings = Object.entries(values).map(([name, value]) => ({ value, metric: { name } }))
    await addCollectionMutation({ variables: {readings, date} })
    history.push("/");
  }

  return <>
    <Navbar title="Home" color="primary" />
    <Content>
      {loading && <Backdrop open={loading} >
        <CircularProgress />
      </Backdrop>}
      {error && <Alert severity="error">Something Went Horribly Wrong</Alert>}
      <Grid container spacing={3}>
        <Grid item sm={12}>
          <Card style={{ padding: 30 }}>
            <TextField
              label="Date"
              type="date"
              defaultValue={date}
              InputLabelProps={{
                shrink: true,
              }}
              style={{ marginRight: 20 }}
              onChange={e => setDate(e.target.value)}
            />
          </Card>
        </Grid>
        {metrics.map(({ name }, index) => <Grid item key={index} sm={12} md={6} lg={3}>
          <Card style={{ textAlign: "center" }}>
            <CardContent>
              <TextField
                label={name}
                type="number"
                defaultValue={0}
                InputLabelProps={{
                  shrink: true,
                }}
                style={{ marginRight: 20 }}
                onChange={e => setValues({...values, [name]: e.target.value})}
              />
            </CardContent>
          </Card>
        </Grid>)}
        <Grid item sm={12} style={{textAlign: "right"}}>
          <UglyButton onClick={submitMetrics}>Add Readings</UglyButton>
        </Grid>
      </Grid>
    </Content>
  </>
}
Example #26
Source File: FavoriteButton.js    From climatescape.org with MIT License 5 votes vote down vote up
export default function FavoriteButton({
  recordId,
  className,
  count: propCount,
  favoriteId: propFavoriteId,
}) {
  const { isAuthenticated, loginWithRedirect } = useAuth0()
  const [favoriteId, setFavoriteId] = useState()
  const [count, setCount] = useState()
  const favorited = !!favoriteId

  useMemo(() => {
    setFavoriteId(propFavoriteId)
    setCount(propCount || 0)
  }, [propFavoriteId, propCount])

  const [addFavorite, { loading: addLoading }] = useMutation(AddFavorite, {
    variables: { recordId },
    refetchQueries: ["GetFavorites"],
    onCompleted: data => {
      setFavoriteId(data.insertFavorites.returning[0].id)
      setCount(count + 1)
    },
  })

  const [deleteFavorite, { loading: deleteLoading }] = useMutation(
    DeleteFavorite,
    {
      variables: { id: favoriteId },
      refetchQueries: ["GetFavorites"],
      onCompleted: () => {
        setFavoriteId(undefined)
        setCount(count - 1)
      },
    }
  )

  const handleClick = event => {
    event.preventDefault()

    if (!isAuthenticated) loginWithRedirect()
    else if (addLoading || deleteLoading) noop()
    else if (!favorited) addFavorite()
    else deleteFavorite()
  }

  return (
    <button
      className={classnames(
        "text-gray-600 h-16 ml-4 px-4 py-2 flex-shrink-0 sm:self-center text-center rounded hover:bg-gray-200",
        className
      )}
      onClick={handleClick}
    >
      <FontAwesomeIcon
        icon={favorited ? heartFilled : heartOutline}
        className={classnames("fill-curent text-lg", {
          "text-red-500": favorited,
        })}
      />
      <div className="text-sm">{count}</div>
    </button>
  )
}
Example #27
Source File: about-us-title-edit-form.js    From horondi_admin with MIT License 5 votes vote down vote up
AboutUsTitleEditForm = ({ businessPage }) => {
  const dispatch = useDispatch();

  const [updateTitle, { loading }] = useMutation(updateBusinessText, {
    onCompleted: () => {
      dispatch(showSuccessSnackbar(SUCCESS_UPDATE_STATUS));
    },
    onError: () => {
      dispatch(showErrorSnackbar(ERROR_BOUNDARY_STATUS));
    }
  });

  const onSubmit = (onSubmitValues) => {
    const updatedBusinessPage = getBusinessPageWithUpdatedTitle(
      businessPage,
      onSubmitValues
    );
    updateTitle({
      variables: setVariablesForUpdatingPage(updatedBusinessPage)
    });
  };

  const { values, errors, touched, handleChange, handleBlur, submitForm } =
    useFormik({
      initialValues: getInitialValuesForTitleEditing(businessPage),
      validationSchema: titleEditValidationSchema,
      onSubmit
    });

  const inputOptions = {
    errors,
    touched,
    handleChange,
    handleBlur,
    values,
    inputs: [titleEditInput]
  };

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

  return (
    <div>
      <EditingButtonsPanel
        pathBack={pathToAboutUs}
        submitForm={submitForm}
        values={values}
        errors={errors}
      />
      <form>
        {languages.map((lang) => (
          <LanguagePanel lang={lang} inputOptions={inputOptions} key={lang} />
        ))}
      </form>
    </div>
  );
}
Example #28
Source File: useAuth.js    From gatsby-apollo-wpgraphql-jwt-starter with MIT License 5 votes vote down vote up
useProvideAuth = () => {
  const [refreshToken, { data }] = useMutation(REFRESH_TOKEN)

  const isOnline = useNetwork()

  // const isAuthTokenExpired = () =>
  //   getInMemoryAuthToken().authToken && isTokenExpired(getInMemoryAuthToken().authToken)

  const isLoggedIn = () =>
    getInMemoryAuthToken() && !isTokenExpired(getInMemoryAuthToken())

  useEffect(() => {
    // TODO: This should only happen in one place. Either we implement an
    //       interval here, or we use the apollo-link-token-refresh in client.js
    if (isOnline && getRefreshToken()) {
      refreshToken({
        variables: {
          input: {
            clientMutationId: uuid(),
            jwtRefreshToken: getRefreshToken(),
          },
        },
      }).then((response) => {
        console.log("silentRefresh", response)
        const token = response.data.refreshJwtAuthToken ? response.data.refreshJwtAuthToken.authToken : null
        if (token) {
          setAuthToken(response.data.refreshJwtAuthToken.authToken)
        }
      })
    }
  }, [refreshToken])


  /**
   * Make sure, User is logged out on all Tabs
   */
  useEffect(() => {
    window.addEventListener("storage", syncLoginStatus)

    return () => {
      window.removeEventListener("storage", syncLoginStatus)
    }
  })

  // TODO: this still needs to be implemented properly
  // useEffect(() => {
  //   console.log("useEffect called")
  //   if (isAuthTokenExpired() && isOnline) {
  //     console.log("Triggered Token Refresh")
  //     /**
  //      * Execute an arbitrary query to trigger auth token refresh,
  //      * then sync local storage with auth context.
  //      */
  //     client
  //     .query({
  //       query: gql`
  //         {
  //           generalSettings {
  //             title
  //           }
  //         }
  //       `,
  //     })
  //   }
  // })

  return {
    isLoggedIn,
    // user: token ? token.user : null,
  }
}
Example #29
Source File: Speakers.jsx    From Consuming-GraphqL-Apollo with MIT License 5 votes vote down vote up
SpeakerList = () => {

  const { loading, error, data } = useQuery(SPEAKERS);

  const [ markFeatured ] = useMutation(FEATURED_SPEAKER);
  
	if (loading) return <p>Loading speakers...</p>
	if (error) return <p>Error loading speakers!</p>

  return data.speakers.map(({ id, name, bio, sessions, featured }) => (
		<div
      key={id}
      className="col-xs-12 col-sm-6 col-md-6"
      style={{ padding: 5 }}
    >
      <div className="panel panel-default">
        <div className="panel-heading">
          <h3 className="panel-title">{'Speaker: '+ name}</h3>
        </div>
        <div className="panel-body">
          <h5>{'Bio: '+ bio }</h5>
        </div>
        <div className="panel-footer">
          <h4>Sessions</h4>
					{
						sessions.map((session) => (
							<span key={session.id}>
              	<p>{session.title}</p>
           		</span>
						))
					}
          <span>	
            <button	
              type="button"	
              className="btn btn-default btn-lg"	
              onClick={ async() => {
                await markFeatured({ variables: {
                  speakerId: id, featured: true
                }})
              }}	
              >	
                <i	
                  className={`fa ${featured ? "fa-star" : "fa-star-o"}`}	
                  aria-hidden="true"	
                  style={{	
                    color: featured ? "gold" : undefined,	
                  }}	
                ></i>{" "}	
                Featured Speaker	
              </button>	
            </span>
        </div>
      </div>
    </div>
	));
}