@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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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>
)
}