@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: 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 #2
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 #3
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 #4
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 #5
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 #6
Source File: use-delete-product-from-wishlist-handler.js    From horondi_client_fe with MIT License 6 votes vote down vote up
export default function useDeleteProductFromWishlistHandler() {
  const user = getFromLocalStorage(USER_TOKENS.ACCESS_TOKEN);

  const [wishlist, setWishlist] = useState(getFromLocalStorage(WISHLIST_KEY));
  const [deleteProductMutation, { error, data, loading }] = useMutation(deleteProductFromWishlist);

  return [
    {
      error: user ? error : null,
      loading: user ? loading : false,
      wishlist: user ? data?.deleteProductFromWishlist.products : wishlist.products
    },
    (product) => {
      if (!user) {
        setToLocalStorage(WISHLIST_KEY, {
          ...wishlist,
          products: wishlist.products.filter(
            (el) => JSON.stringify(el._id) !== JSON.stringify(product._id)
          )
        });

        setWishlist(getFromLocalStorage(WISHLIST_KEY));
      } else deleteProductMutation({ variables: { productId: product._id } });
    }
  ];
}
Example #7
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 #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: 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 #10
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 #11
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>
	));
}
Example #12
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 #13
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 #14
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 #15
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 #16
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 #17
Source File: mail-form.spec.js    From horondi_client_fe with MIT License 5 votes vote down vote up
useMutation.mockImplementation(() => [
  jest.fn(),
  {
    loading: false,
    error: null,
    data: { sendEmailMutation: [{ addEmailQuestion: { question: { senderName: 'name' } } }] }
  }
]);
Example #18
Source File: index.js    From realworld with MIT License 5 votes vote down vote up
function ArticlePage() {
  const router = useRouter();
  const skip = !router.query.slug;
  const page = useQuery(ArticlePageQuery, {
    variables: queryToVariables(router.query),
    skip,
  });

  const [deleteArticle] = useMutation(ArticlePageDeleteArticleMutation);
  const [favoriteArticle] = useMutation(ArticlePageFavoriteArticleMutation);
  const [followUser] = useMutation(ArticlePageFollowUserMutation);
  const [unfavoriteArticle] = useMutation(ArticlePageUnfavoriteArticleMutation);
  const [unfollowUser] = useMutation(ArticlePageUnfollowUserMutation);

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

  return (
    <Layout {...page.data.viewer}>
      <div className="article-page">
        <ArticlePageBanner
          onDelete={deleteArticle}
          onFavorite={favoriteArticle}
          onFollow={followUser}
          onUnfavorite={unfavoriteArticle}
          onUnfollow={unfollowUser}
          {...page.data.article}
        />
        <div className="container page">
          <ArticleContent {...page.data.article} />
          <hr />
          <div className="article-actions">
            <ArticleMeta
              onDelete={deleteArticle}
              onFavorite={favoriteArticle}
              onFollow={followUser}
              onUnfavorite={unfavoriteArticle}
              onUnfollow={unfollowUser}
              {...page.data.article}
            />
          </div>
          <div className="row">
            <div className="col-xs-12 col-md-8 offset-md-2">
              <ArticleComments articleSlug={page.data.article.slug} />
            </div>
          </div>
        </div>
      </div>
    </Layout>
  );
}
Example #19
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 #20
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 #21
Source File: login.js    From next-ecommerce with MIT License 4 votes vote down vote up
export default function Login() {
  const client = useApolloClient();
  const [signIn] = useMutation(SIGN_IN);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [msgError, setMsgError] = useState('');

  const router = useRouter();

  async function handleSubmit(e) {
    e.preventDefault();

    try {
      await client.resetStore();
      const { data } = await signIn({
        variables: {
          email: email.trim(),
          password: password.trim(),
        },
      });
      if (data.signIn.user) {
        await router.push('/');
      }
    } catch (error) {
      setMsgError(getErrorMessage(error));
    }
  }

  return (
    <PageContainer title="Quantum E-commerce - Login">
      <FormContainer>
        <form onSubmit={handleSubmit}>
          <h3 className="formTitle">login</h3>

          {msgError && <AlertError message={msgError} />}

          <InputContainer>
            <Input
              type="email"
              name="email"
              placeholder="Email"
              onChange={(value) => setEmail(value)}
              value={email}
            />
            <Input
              type="password"
              name="password"
              placeholder="Password"
              onChange={(value) => setPassword(value)}
              value={password}
            />

            <Button type="submit" title="Login" />
          </InputContainer>
        </form>

        <Link href="/user/signup">
          <a className="switchForm">I do not have a account</a>
        </Link>
        <Link href="/user/resetpassword">
          <a className="switchForm">I forgot my password</a>
        </Link>
      </FormContainer>

      <style jsx>{`
        form {
          width: 100%;
          align-items: center;
        }
        form .formTitle {
          text-align: center;
          font-size: 38px;
          font-weight: 1000;
          letter-spacing: 1.65px;
          color: #b2b2b2;
          text-transform: uppercase;
          margin-bottom: 84px;
        }
        .switchForm {
          color: #b2b2b2;
          margin-top: 12px;
          font-weight: 500;
        }
      `}</style>
    </PageContainer>
  );
}
Example #22
Source File: FirebaseLoginForm.js    From RC4Community with Apache License 2.0 4 votes vote down vote up
export default function FirebaseLoginForm({onSignupClick}){
    const [upsertUserFunc, { data, loading, error }] = useMutation(UPSERT_USER);
    const [email,setEmail] = useState("");
    const [password,setPassword] = useState("");
    const [errorMessage,setError] = useState("");
    const [diffCredError,setDiffCredError] = useState(null);
    const [progress,setProgress] = useState(false);

    if(error) console.log("Error Provider = ", error)
    if(data) console.log("Data = ", data)
    if(loading) console.log("Loading = ", loading)

    const doEmailPasswordLogin = async (e) => {
        e.preventDefault();
        if(progress){
            return true;
        }
        setProgress(true);
        try {
            const fbApp = getApp(FB_APP_NAME);
            const userCred = await signInWithEmailAndPassword(getAuth(fbApp),email,password);
            Cookies.set('user', userCred.user.uid);
            if(diffCredError?.oldProvider?.providerId === EmailAuthProvider.PROVIDER_ID){
                // The signin was requested to link new credentials with the account 
                await linkWithCredential(userCred.user,OAuthProvider.credentialFromError(diffCredError.error));
            }

        } catch(error){
            switch(error.code){
                case 'auth/user-not-found':
                    setError("User not found");
                    break;
                case 'auth/wrong-password':
                    setError("Incorrect Password");
                    break;
                default:
                    setError("Unknown error occurred");
            }
        } finally {
            setProgress(false);
        }
    }
    const handleProviderSignIn = async provider => {
        if(progress){
            return;
        }
        const fbApp = getApp(FB_APP_NAME);
        const auth = getAuth(fbApp);
        try {
            const userCred = await signInWithPopup(auth,provider);
            Cookies.set('user', userCred.user.uid);
            await upsertUserFunc({
                variables: {
                    uid: userCred.user.uid,
                    email: userCred.user.email,
                    displayName: userCred.user.displayName,
                    phoneNumber: userCred.user.phoneNumber,
                    photoURL: userCred.user.photoURL
                },
              })
            if(diffCredError){
                // The signin was requested to link new credentials with the account 
                await linkWithCredential(userCred.user,OAuthProvider.credentialFromError(diffCredError.error));
            }
        } catch (e){
            switch(e.code){
                case 'auth/popup-closed-by-user':
                case 'auth/cancelled-popup-request':
                    break;
                case 'auth/popup-blocked':
                    setError("Popup blocked by your browser.")
                    break;
                case 'auth/account-exists-with-different-credential':
                    const methods = await fetchSignInMethodsForEmail(auth,e.customData.email);;
                    setDiffCredError({error: e, newProviderId: provider.providerId ,oldProviderId: methods[0]});
                    break;
                default:
                    setError("Unknown error occurred");
            }
            setProgress(false);
        }
    }
    
    const onGoogleBtnClick = () => {
        if(progress){
            return;
        }
        setProgress(true);
        const provider = new GoogleAuthProvider();
        handleProviderSignIn(provider);
    }
    
    const onFacebookBtnClick = () => {
        if(progress){
            return;
        }
        setProgress(true);
        const provider = new FacebookAuthProvider();
        handleProviderSignIn(provider);
    }

    return (
        <div className="container-fluid p-1">
            <form className="container-fluid" onSubmit={doEmailPasswordLogin}>
                <FormControl
                    type="text" 
                    placeholder="email" 
                    className="mb-1" 
                    disabled={progress}
                    onChange={e=> setEmail(e.target.value)}/>
                <FormControl 
                    type="password" 
                    placeholder="password" 
                    className="mb-1"
                    disabled={progress}
                    onChange={e => setPassword(e.target.value)}/>
                {
                    errorMessage &&
                    <Alert variant="danger" className="mb-1">{errorMessage}</Alert>
                }
                <div className="d-flex justify-content-between">
                    <Button 
                        type="submit" 
                        className="mb-1" 
                        disabled={progress}>
                            Login
                    </Button>
                    <Button 
                        className="mb-1" 
                        variant="light"
                        disabled={progress}
                        onClick={onSignupClick}>
                        Sign up
                    </Button>
                </div>
            </form>
            <div className="container-fluid d-flex flex-column">
                <Button 
                    variant="danger" 
                    className="mb-1"
                    onClick={onGoogleBtnClick} 
                    disabled={progress}>
                        Sign in with Google
                </Button>
                <Button 
                    className="mb-1"
                    onClick={onFacebookBtnClick}  
                    disabled={progress}>
                        Sign in with Facebook
                </Button>
            </div>
            {
                diffCredError &&
                <div className="p-1 mb-1">
                    <Alert variant="danger" className="mb-1">
                        User's email already exists. Sign in with {diffCredError.oldProviderId} to link your {diffCredError.newProviderId} account.
                    </Alert>
                </div>
            }
        </div>
    )
}
Example #23
Source File: BankTransferFlow.js    From ucurtmetre with GNU General Public License v3.0 4 votes vote down vote up
function BankTransferFlow() {
  const location = useLocation();
  const [currentBank, setCurrentBank] = React.useState(-1);
  const blAuth = localStorage.getItem('blAuth');

  const [
    collectDonation,
    { data: donationData, error: donationError, loading: donationLoading },
  ] = useMutation(COLLECT_DONATION, { onError: err => err });

  const [getOauthUrl, { data }] = useLazyQuery(GET_OAUTH_URL, {
    variables: {
      campaignId: 'donate-all',
      returnUrl: 'https://destek.ucurtmaprojesi.com/auth/callback',
    },
  });

  const [
    getBanks,
    { error: bankError, data: bankData, loading: bankLoading },
  ] = useLazyQuery(GET_BANKS, {
    context: {
      headers: {
        oauth2: blAuth,
      },
    },
  });

  useEffect(() => {
    if (blAuth) {
      getBanks();
    } else {
      getOauthUrl();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (bankError) {
      localStorage.removeItem('blAuth');
      getOauthUrl();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [bankError]);

  return (
    <div className="bank-transfer-flow">
      {location.state?.state?.redirectError && (
        <Alert
          icon={<AlertCircle />}
          variant="danger"
          message="BiLira ile bağlantı kurulurken bir hata oluştu. Lütfen daha sonra tekrar deneyin."
        />
      )}
      <Alert
        message={
          <>
            <p>
              Yapacağınız destekleri güvenli ve hızlı bir şekilde öğrencimize
              ulaştırabilmek için{' '}
              <a
                href="https://www.bilira.co/"
                target="_blank"
                rel="noopener noreferrer"
              >
                BiLira
              </a>{' '}
              ile çalışıyoruz.
            </p>
            {!blAuth && (
              <p>
                Aşağıdaki butonu kullanarak hızlıca hesap oluşturabilir, varolan
                hesabınızla transferi yapacağınız banka hesabına kolayca
                ulaşabilirsiniz.
              </p>
            )}
          </>
        }
        icon={<AlertCircle />}
      />
      {bankLoading && (
        <div>
          <Skeleton count={4} />
        </div>
      )}
      {data && !blAuth && (
        <a
          className="login-with-bilira"
          href={data.biliraOAuthUrl.authorizationUri}
        >
          BiLira ile giriş yap
        </a>
      )}
      {bankData && !donationData && (
        <>
          <SelectBank
            bankData={bankData}
            onSelect={bankId => setCurrentBank(bankId)}
            selectedBank={currentBank}
          />
          {currentBank !== -1 && (
            <Formik
              initialValues={{
                email: '',
                amount: '',
                consentToReceiveNews: false,
                consentToUserAgreement: false,
              }}
              validationSchema={bankTransferValidation}
              onSubmit={async (values, { setSubmitting }) => {
                setSubmitting(true);
                collectDonation({
                  variables: {
                    campaignCode: 'campaign-all',
                    bankId: parseInt(currentBank, 10),
                    email: values.email,
                    amount: parseFloat(values.amount),
                  },
                  context: {
                    headers: {
                      oauth2: blAuth,
                    },
                  },
                });
              }}
            >
              {({ isSubmitting, dirty, isValid }) => (
                <Form data-private>
                  <div>
                    <Input
                      label="Email"
                      name="email"
                      type="email"
                      placeholder="Lütfen email adresinizi girin."
                    />

                    <Input
                      label="Miktar"
                      name="amount"
                      type="number"
                      placeholder="Lütfen göndermek istediğiniz destek miktarını giriniz."
                    />
                  </div>

                  <Agreements
                    kvkkName="consentToReceiveNews"
                    agreementName="consentToUserAgreement"
                  />

                  <button
                    className="button secondary-button submit"
                    type="submit"
                    disabled={
                      isSubmitting || !dirty || !isValid || donationLoading
                    }
                    width="full"
                  >
                    Destekle
                  </button>
                </Form>
              )}
            </Formik>
          )}
        </>
      )}
      {(donationData || donationError) && (
        <BankDetailViewer error={donationError} data={donationData} />
      )}
    </div>
  );
}
Example #24
Source File: Sessions.jsx    From Consuming-GraphqL-Apollo with MIT License 4 votes vote down vote up
export function SessionForm() {	

  const updateSessions = (cache, { data }) => {
    cache.modify({ 
      fields: {
        sessions(exisitingSessions = []) {
          const newSession = data.createSession;
          cache.writeQuery({
            query: ALL_SESSIONS,
            data: { newSession, ...exisitingSessions }
          });
        }
      }
    })
  };

  const [ create, { called, error } ] = useMutation(CREATE_SESSION, {
    update: updateSessions
  });

  if(called) return <p>Session Submitted Successfully!</p>

  if(error) return <p>Failed to submit session</p>

  return (	
    <div	
      style={{	
        width: "100%",	
        display: "flex",	
        alignContent: "center",	
        justifyContent: "center",	
        padding: 10,	
      }}	
    >	
      <Formik	
        initialValues={{	
          title: "",	
          description: "",	
          day: "",	
          level: "",	
        }}	
        onSubmit={ async (values) => {
          await create({ variables: {session: values }});
        }}	
      >	
        {() => (	
          <Form style={{ width: "100%", maxWidth: 500 }}>	
            <h3 className="h3 mb-3 font-weight-normal">Submit a Session!</h3>	
            <div className="mb-3" style={{ paddingBottom: 5 }}>	
              <label htmlFor="inputTitle">Title</label>	
              <Field	
                id="inputTitle"	
                className="form-control"	
                required	
                autoFocus	
                name="title"	
              />	
            </div>	
            <div className="mb-3" style={{ paddingBottom: 5 }}>	
              <label htmlFor="inputDescription">Description</label>	
              <Field	
                type="textarea"	
                id="inputDescription"	
                className="form-control"	
                required	
                name="description"	
              />	
            </div>	
            <div className="mb-3" style={{ paddingBottom: 5 }}>	
              <label htmlFor="inputDay">Day</label>	
              <Field	
                name="day"	
                id="inputDay"	
                className="form-control"	
                required	
              />	
            </div>	
            <div className="mb-3" style={{ paddingBottom: 5 }}>	
              <label htmlFor="inputLevel">Level</label>	
              <Field	
                name="level"	
                id="inputLevel"	
                className="form-control"	
                required	
              />	
            </div>	
            <div style={{ justifyContent: "center", alignContent: "center" }}>
              <button className="btn btn-primary">Submit</button>	
            </div>
          </Form>	
        )}	
      </Formik>	
    </div>	
  );	
}
Example #25
Source File: AnswerForm.js    From stack-underflow with MIT License 4 votes vote down vote up
AnswerForm = ({ quesId, tags }) => {
  const classes = useQuesPageStyles();
  const { user } = useAuthContext();
  const { clearEdit, notify } = useStateContext();
  const { register, handleSubmit, reset, errors } = useForm({
    mode: 'onChange',
    resolver: yupResolver(validationSchema),
  });

  const [addAnswer, { loading }] = useMutation(POST_ANSWER, {
    onError: (err) => {
      notify(getErrorMsg(err), 'error');
    },
  });

  const postAnswer = ({ answerBody }) => {
    addAnswer({
      variables: { quesId, body: answerBody },
      update: (proxy, { data }) => {
        reset();

        const dataInCache = proxy.readQuery({
          query: VIEW_QUESTION,
          variables: { quesId },
        });

        const updatedData = {
          ...dataInCache.viewQuestion,
          answers: data.postAnswer,
        };

        proxy.writeQuery({
          query: VIEW_QUESTION,
          variables: { quesId },
          data: { viewQuestion: updatedData },
        });

        notify('Answer submitted!');
      },
    });
  };

  return (
    <div className={classes.answerForm}>
      {user && (
        <Typography variant="h6" color="secondary">
          Your Answer
        </Typography>
      )}
      {user && (
        <form onSubmit={handleSubmit(postAnswer)}>
          <TextField
            inputRef={register}
            name="answerBody"
            required
            fullWidth
            type="text"
            placeholder="Enter atleast 30 characters"
            variant="outlined"
            size="small"
            error={'answerBody' in errors}
            helperText={'answerBody' in errors ? errors.answerBody.message : ''}
            multiline
            rows={5}
          />
          <div>
            <Button
              color="primary"
              variant="contained"
              style={{ marginTop: '0.8em' }}
              type="submit"
              disabled={loading}
            >
              Post Your Answer
            </Button>
          </div>
        </form>
      )}
      <div className={classes.footerText}>
        <span>
          Browse other questions tagged{' '}
          {tags.map((t) => (
            <Chip
              key={t}
              label={t}
              variant="outlined"
              color="primary"
              size="small"
              component={RouterLink}
              to={`/tags/${t}`}
              className={classes.footerTag}
              clickable
            />
          ))}
          or{' '}
          {user ? (
            <Link component={RouterLink} to="/ask" onClick={() => clearEdit()}>
              ask your own question.
            </Link>
          ) : (
            <AuthFormModal buttonType="link" />
          )}
        </span>
      </div>
    </div>
  );
}
Example #26
Source File: index.js    From nextjs-boilerplate with MIT License 4 votes vote down vote up
Navigation = ({ user, logoutOnClient }) => {
  const router = useRouter();
  const [logoutOnServer] = useMutation(logoutMutation);

  const handleLogout = (event) => {
    event.stopPropagation();
    logoutOnServer().then(() => {
      logoutOnClient();
      router.push("/login");
    });
  };

  return (
    <nav className="navbar navbar-expand-lg navbar-light bg-light">
      <div className="container">
        <Link href="/">
          <a className="navbar-brand" href="#">
            App
          </a>
        </Link>
        <button
          className="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarNav"
          aria-controls="navbarNav"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span className="navbar-toggler-icon"></span>
        </button>
        <div className="collapse navbar-collapse" id="navbarNav">
          {user && (
            <ul className="navbar-nav">
              <li className="nav-item">
                <Link href="/documents">
                  <a
                    className={`nav-link ${
                      "/documents" === router.pathname ? "active" : ""
                    }`}
                  >
                    Documents
                  </a>
                </Link>
              </li>
            </ul>
          )}
          {user ? (
            <ul className="navbar-nav ms-auto">
              <li className="nav-item dropdown">
                <a
                  href="#"
                  className="nav-link dropdown-toggle"
                  id="navbarDropdown"
                  role="button"
                  data-bs-toggle="dropdown"
                  aria-expanded="false"
                >
                  {user && user.emailAddress}
                </a>
                <ul className="dropdown-menu" aria-labelledby="navbarDropdown">
                  <li onClick={handleLogout}>
                    <a href="#" className="dropdown-item">
                      Logout
                    </a>
                  </li>
                </ul>
              </li>
            </ul>
          ) : (
            <ul className="navbar-nav ms-auto">
              <li className="nav-item">
                <Link href="/login">
                  <a
                    className={`nav-link ${
                      "/login" === router.pathname ? "active" : ""
                    }`}
                  >
                    Login
                  </a>
                </Link>
              </li>
              <li className="nav-item">
                <Link href="/signup">
                  <a
                    className={`nav-link ${
                      "/signup" === router.pathname ? "active" : ""
                    }`}
                  >
                    Signup
                  </a>
                </Link>
              </li>
            </ul>
          )}
        </div>
      </div>
    </nav>
  );
}
Example #27
Source File: about-us-footer-img-edit-form.js    From horondi_admin with MIT License 4 votes vote down vote up
AboutUsFooterImgEditForm = ({ businessPage }) => {
  const [businessPageData, setBusinessPageData] = useState(businessPage);
  const [upload, setUpload] = useState();
  const styles = useStyles();
  const dispatch = useDispatch();

  const [updateSection, { loading: updateSectionLoading }] = useMutation(
    updateBusinessText,
    {
      onCompleted: (data) => {
        if (data?.updateBusinessText?.message) {
          dispatch(showErrorSnackbar(ERROR_BOUNDARY_STATUS));
        } else {
          setBusinessPageData(data.updateBusinessText);
          dispatch(showSuccessSnackbar(SUCCESS_UPDATE_STATUS));
        }
      },
      onError: () => {
        dispatch(showErrorSnackbar(ERROR_BOUNDARY_STATUS));
      }
    }
  );

  const [deleteImg, { loading: deleteImgLoading }] = useMutation(deleteFiles);

  const onSubmit = () => {
    const imgNames = getFooterImgNames(businessPageData);
    deleteImg({ variables: { fileNames: imgNames } });

    const updatedBusinessPage = getBusinessPageWithUpdatedFooterImg(
      businessPageData,
      upload?.name
    );

    const variables = setVariablesForUpdatingPage(updatedBusinessPage, [
      upload
    ]);

    updateSection({
      variables
    });
  };

  const { values, errors, setFieldValue, submitForm } = useFormik({
    initialValues: getInitialValuesForFooterImgEdit(businessPageData),
    validationSchema: footerImgEditValidationSchema,
    onSubmit
  });

  const handleImageLoad = (files) => {
    const reader = new FileReader();
    reader.onload = (event) => {
      setFieldValue(img, event.target.result);
    };
    reader.readAsDataURL(files[0]);
    setUpload(files[0]);
  };

  if (updateSectionLoading || deleteImgLoading) {
    return <LoadingBar />;
  }

  return (
    <div>
      <EditingButtonsPanel
        pathBack={pathToAboutUs}
        submitForm={submitForm}
        values={values}
        errors={errors}
      />
      <form>
        <Grid container spacing={1}>
          <Grid item xs={12}>
            <Typography className={styles.title} variant='h5'>
              {img.toUpperCase()}
            </Typography>
            <Paper className={styles.paper}>
              <div className={styles.imageUploadContainer}>
                <ImageUploadContainer
                  handler={handleImageLoad}
                  src={values.img}
                />
              </div>
            </Paper>
          </Grid>
        </Grid>
      </form>
    </div>
  );
}
Example #28
Source File: active-messenger.js    From horondi_client_fe with MIT License 4 votes vote down vote up
ActiveMessenger = ({ iconsVisible, mailFormVisible }) => {
  const style = useStyles({ iconsVisible, mailFormVisible });
  const { t, i18n } = useTranslation();

  const { userData } = useSelector(({ User }) => ({
    userData: User.userData
  }));
  const defaultFirstName = get(userData, 'firstName', '');
  const defaultEmail = get(userData, 'email', '');
  const language = i18n.language === 'ua' ? 0 : 1;

  const [user, setUser] = useState({
    ...CHAT_USER_DATA,
    firstName: defaultFirstName,
    email: defaultEmail
  });
  const { firstName, email, message } = user;

  const [firstNameValidated, setFirstNameValidated] = useState(!!defaultFirstName);
  const [emailValidated, setEmailValidated] = useState(!!defaultEmail);
  const [messageValidated, setMessageValidated] = useState(false);
  const [allFieldsValidated, setAllFieldsValidated] = useState(false);
  const [shouldValidate, setShouldValidate] = useState(false);
  const [open, setOpen] = useState(false);
  const [sendEmail, { loading, error }] = useMutation(sendEmailMutation);

  const helperTextForName =
    firstName.length < TWO_LETTERS || firstName.length > THIRTY_LETTERS
      ? handleHelperText(firstNameValidated, shouldValidate, 'profile.firstName')
      : handleHelperText(firstNameValidated, shouldValidate, 'onlyLetter');

  const handleChange = (event, setValid, regExp) => {
    const input = event.target.value;
    const inputName = event.target.name;
    setUser({ ...user, [inputName]: input });
    input.match(regExp) ? setValid(true) : setValid(false);
  };

  const handleValidForms = () => {
    setShouldValidate(true);
    allFieldsValidated && sendHandler();
  };

  const handleClick = () => {
    setOpen(true);
    setUser(CHAT_USER_DATA);
  };

  const sendHandler = () => {
    setAllFieldsValidated(false);
    sendEmail({
      variables: {
        email,
        senderName: firstName,
        text: message,
        language
      }
    });
    handleClick();
  };

  const handleClose = (_event, reason) => {
    if (reason === 'clickaway') {
      return;
    }
    setOpen(false);
  };

  const Alert = (props) => <MuiAlert elevation={6} variant='filled' {...props} />;

  useEffect(() => {
    if (firstNameValidated && emailValidated && messageValidated) {
      setAllFieldsValidated(true);
    } else {
      setAllFieldsValidated(false);
    }
  }, [firstNameValidated, emailValidated, messageValidated]);

  if (loading || error) return errorOrLoadingHandler(error, loading);

  return (
    <form className={style.contactForm}>
      <span className={style.mailTitle}>{t('chat.sendMail')}</span>
      <>
        <TextField
          required
          fullWidth
          key={t('common.name')}
          label={t('common.name')}
          variant='outlined'
          name='firstName'
          size='small'
          rows={1}
          error={!firstNameValidated && shouldValidate}
          helperText={helperTextForName}
          className={style.dataInput}
          onChange={(e) => handleChange(e, setFirstNameValidated, formRegExp.firstName)}
          value={firstName}
          type='text'
        />
        <TextField
          required
          fullWidth
          key={t('common.email')}
          label={t('common.email')}
          variant='outlined'
          name='email'
          size='small'
          rows={1}
          error={!emailValidated && shouldValidate}
          helperText={handleHelperText(emailValidated, shouldValidate, 'profile.email')}
          className={style.dataInput}
          onChange={(e) => handleChange(e, setEmailValidated, formRegExp.email)}
          value={email}
          type='text'
        />
        <TextField
          fullWidth
          key={t('chat.msgText')}
          label={t('chat.msgText')}
          variant='outlined'
          name='message'
          multiline
          rows={10}
          inputProps={{ maxLength: 500 }}
          error={!messageValidated && shouldValidate}
          helperText={handleHelperText(messageValidated, shouldValidate, 'profile.message')}
          className={style.dataInput}
          onChange={(e) => handleChange(e, setMessageValidated, formRegExp.text)}
          value={message}
          type='text'
          required
        />
      </>
      <Snackbar open={open} autoHideDuration={1500} onClose={handleClose}>
        <Alert onClose={handleClose} severity='success'>
          {t('chat.thanksMsg')}
        </Alert>
      </Snackbar>
      <Button className={style.btnSend} onClick={handleValidForms}>
        {t('buttons.sendBtn')}
      </Button>
    </form>
  );
}
Example #29
Source File: Episode.js    From grandcast.fm with Apache License 2.0 4 votes vote down vote up
Episode = ({ episode, playlists }) => {
  const [addEpisode] = useMutation(ADD_EPISODE_TO_PLAYLIST)

  const isEpisodeInPlaylist = (playlistName) => {
    const playlist = playlists.filter((i) => {
      return playlistName === i.name
    })

    const episodes = playlist[0].episodes?.map((v) => {
      return v.id
    })

    return episodes?.includes(episode.id)
  }

  return (
    <Flex
      border="1px"
      rounded="lg"
      style={{ maxWidth: '700px', width: '100%' }}
    >
      <Box w="150px">
        <Image boxSize="150px" src={episode.podcast.image} m={2} />
        <Menu m={2} w="150px">
          <MenuButton m={2} w="150px" as={Button}>
            <AddIcon />
          </MenuButton>
          <MenuList>
            {playlists?.map((v) => {
              return (
                <MenuItem
                  icon={isEpisodeInPlaylist(v.name) ? <CheckIcon /> : null}
                  key={v.name}
                  onClick={() =>
                    addEpisode({
                      variables: {
                        episodeId: episode.id,
                        playlistName: v.name,
                      },
                    })
                  }
                >
                  {v.name}
                </MenuItem>
              )
            })}
          </MenuList>
        </Menu>
      </Box>
      <Flex direction="column" ml={4} w="100%">
        <div>
          <Accordion allowToggle>
            <AccordionItem>
              <h2>
                <AccordionButton>
                  <Box flex="1" textAlign="left">
                    <Heading size="sm">{episode.title}</Heading>
                  </Box>
                  <AccordionIcon />
                </AccordionButton>
              </h2>
              <AccordionPanel pb={4} m={4}>
                <div dangerouslySetInnerHTML={{ __html: episode.summary }} />
              </AccordionPanel>
            </AccordionItem>
          </Accordion>
        </div>
        <Flex direction="column">
          <Text ml={4} fontSize="lg" isTruncated>
            {episode.podcast.title}
          </Text>
          <Text ml={4} as="i">
            {`${moment(episode.pubDate).format('MMMM Do YYYY')}`}
          </Text>
        </Flex>
        <div style={{ marginTop: 'auto' }}>
          <audio style={{ width: '100%' }} controls>
            <source src={episode.audio} type="audio/mpeg"></source>
          </audio>
        </div>
      </Flex>

      {/* <div>{episode.audio}</div>
      <div>{episode.id}</div>
      <div>{episode.podcast.image}</div> */}
    </Flex>
  )
}