@apollo/react-hooks#useMutation JavaScript Examples
The following examples show how to use
@apollo/react-hooks#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: SignIn.jsx From saasgear with MIT License | 6 votes |
function SignIn() {
useDocumentHeader({ title: 'Sign In' });
const { register, handleSubmit, errors: formErrors } = useForm({
resolver: yupResolver(SignInSchema),
});
const [loginMutation, { error, loading }] = useMutation(loginQuery);
const history = useHistory();
async function onSubmit(params) {
try {
const { data } = await loginMutation({ variables: params });
if (data?.login) {
history.push('/');
}
} catch (e) {
console.log(e);
}
return false;
}
return (
<SignUpFormWrapper>
<SignUpFormLeft>
<SignInForm
onSubmit={handleSubmit(onSubmit)}
register={register}
formErrors={formErrors}
apiError={error?.message}
isSubmitting={loading}
/>
</SignUpFormLeft>
<SignUpAds>
<AuthAdsArea />
</SignUpAds>
</SignUpFormWrapper>
);
}
Example #2
Source File: LikeButton.js From 0.4.1-Quarantime with MIT License | 6 votes |
function LikeButton({ user, post: { id, likeCount, likes } }) {
const [liked, setLiked] = useState(false);
useEffect(() => {
if (user && likes.find((like) => like.username === user.username)) {
setLiked(true);
} else setLiked(false);
}, [user, likes]);
const [likePost] = useMutation(LIKE_POST_MUTATION, {
variables: { postId: id }
});
const likeButton = user ? (
liked ? (
<Button color="pink" >
<Icon name="heart" />
</Button>
) : (
<Button color="pink" basic>
<Icon name="heart" />
</Button>
)
) : (
<Button as={Link} to="/login" color="pink" basic>
<Icon name="heart" />
</Button>
);
return (
<Button as="div" labelPosition="right" onClick={likePost}>
<MyPopup content={liked ? 'Unlike' : 'Like'}>{likeButton}</MyPopup>
<Label basic color="pink" pointing="left">
{likeCount}
</Label>
</Button>
);
}
Example #3
Source File: Admin.jsx From saasgear with MIT License | 6 votes |
function AdminLayoutContainer() {
const { data: userPlanData, loading: loadingUserPlan } = useQuery(
getUserPlanQuery,
);
const [logout] = useMutation(logoutQuery);
const dispatch = useDispatch();
const history = useHistory();
useEffect(() => {
dispatch(
setUserPlan({
data: userPlanData?.getUserPlan,
loading: loadingUserPlan,
}),
);
}, [userPlanData, loadingUserPlan]);
async function signout() {
await logout();
history.push('/auth/signin');
}
return <AdminLayout signout={signout} />;
}
Example #4
Source File: CreateProperty.js From willow-grandstack with Apache License 2.0 | 6 votes |
export default function CreateProperty() {
let input
const [createProperty, { data, loading, error }] = useMutation(
CREATE_PROPERTY_MUTATION
)
return (
<div>
<form
onSubmit={(e) => {
e.preventDefault()
createProperty({ variables: { city: input.value } })
input.value = ''
}}
>
<input
ref={(n) => {
input = n
}}
/>
<button type="submit">Add City</button>
</form>
</div>
)
}
Example #5
Source File: ViewPost.js From graphql-sample-apps with Apache License 2.0 | 5 votes |
export default function ViewPost(props) {
const [numLikes, setNumLikes] = useState(0);
const history = useHistory();
const editPost = (postID) => {
history.push({
pathname: '/edit',
search: `?postID=${postID}`
})
}
const postSet = {
numLikes: numLikes +1
}
let params = queryString.parse(props.location.search);
let postID = params.postID;
const { loading, error, data } = useQuery(GET_POST, { variables: { postID }, fetchPolicy: "network-only" });
const [deletePost] = useMutation(DELETE_POST);
const [updatePost] = useMutation(POST_MUTATION);
if (loading) return "Fetching Posts...";
if (error) return `Error: ${error}`;
const post = data.getPost;
if (numLikes === 0) {
setNumLikes(post.numLikes)
}
return (
<div className="container">
<div className="h3 text-center">{post.title}
<span className="delete-post" onClick={async e => {
e.preventDefault();
await deletePost({ variables: { postID } })
history.push({
pathname: '/'
});
}}>
<i className="icon-trash" aria-hidden="true"></i>
</span>
<span className="edit-post" onClick={() => editPost(post.postID)}>
<i className="icon-edit" aria-hidden="true"></i>
</span>
</div>
<hr />
<div className="text-post">{post.text}</div>
<div>
<button type="button" className="btn btn-primary btn-sm" onClick = { async e => {
e.preventDefault()
await updatePost({ variables: { postSet, postID} })
history.push({
pathname: '/',
});
history.push({
pathname: '/view',
search: `?postID=${postID}`
});
}}>
Likes <span className="badge badge-light">{post.numLikes}</span>
</button>
<span className="tagsset-post">
{post.tags.map(tag => (
<span
className="badge badge-secondary tag-post"
key={tag}
>
{tag}
</span>
))}
</span>
</div>
</div>
);
}
Example #6
Source File: Step1.jsx From dineforward with MIT License | 5 votes |
OnboardingStep1 = ({ classes = {}, forward, setBusinessId }) => {
const userId = useIdentity()?.id;
if (!userId) throw new Error(`Unable to get authenticated user information`);
const [createBiz, { loading, error }] = useMutation(CREATE_BIZ_AND_UPDATE_USER, {
onCompleted: data => {
console.log(`createbiz completed`, data);
const id = data?.createBusiness?.id;
if (!id) throw new Error(`Did not receive new business ID back from API`);
setBusinessId(id);
forward();
},
// Must provide onError to avoid unhandled Promise rejection
onError: err => {},
});
const onSubmit = (formData, { setSubmitting }) => {
let { contactPhone, ...bizData } = formData;
bizData = removeEmpty(bizData);
const userData = removeEmpty({ contactPhone });
if (!loading) {
createBiz({
variables: {
bizData,
uid: userId,
userData,
},
})
// Restore submit button
.then(() => setSubmitting(false));
}
};
const errorMsg = getErrorMsg(error);
return (
<Grid container spacing={5} className={classes.root} direction="column" alignItems="center">
{errorMsg && (
<Grid item md={12}>
<Alert severity="error">{errorMsg}</Alert>
</Grid>
)}
<Grid item md={8} xs={12}>
<Typography
className={classes.stepTitle}
variant="subtitle1"
>
{stepTitle}
</Typography>
<ComplexFormBuilder
schema={requestBizForm.form}
formAction={onSubmit}
>
{({ isSubmitting }) => (
<div>
<p>* Required items</p>
<Box display="flex" justifyContent="flex-end" className={classes.buttonBox}>
<Button
type="submit"
variant="contained"
color="primary"
disabled={isSubmitting}
endIcon={<DoubleArrow />}
>
Next
</Button>
</Box>
</div>
)}
</ComplexFormBuilder>
</Grid>
</Grid>
);
}
Example #7
Source File: App.js From todo-react-graphql with MIT License | 5 votes |
function App() {
let input;
const { data, loading, error } = useQuery(READ_TODOS);
const [createTodo] = useMutation(CREATE_TODO);
const [deleteTodo] = useMutation(REMOVE_TODO);
const [updateTodo] = useMutation(UPDATE_TODO);
if (loading) return <p>loading...</p>;
if (error) return <p>ERROR</p>;
if (!data) return <p>Not found</p>;
return (
<div className="app">
<h3>Create New Todo</h3>
<form onSubmit={e => {
e.preventDefault();
createTodo({ variables: { text: input.value } });
input.value = '';
window.location.reload();
}}>
<input className="form-control" type="text" placeholder="Enter todo" ref={node => { input = node; }}></input>
<button className="btn btn-primary px-5 my-2" type="submit">Submit</button>
</form>
<ul>
{data.todos.map((todo) =>
<li key={todo.id} className="w-100">
<span className={todo.completed ? "done" : "pending"}>{todo.text}</span>
<button className="btn btn-sm btn-danger rounded-circle float-right" onClick={() => {
deleteTodo({ variables: { id: todo.id } });
window.location.reload();
}}>X</button>
<button className={`btn btn-sm float-right ${todo.completed ? "btn-success" : "btn-info"}`} onClick={() => {
updateTodo({ variables: { id: todo.id } });
window.location.reload();
}}>{todo.completed ? <span>Completed</span> : <span>Not completed</span>}</button>
</li>
)}
</ul>
</div>
);
}
Example #8
Source File: Login.js From 0.4.1-Quarantime with MIT License | 5 votes |
function Login(props) {
const context = useContext(AuthContext);
const [errors, setErrors] = useState({});
const { onChange, onSubmit, values } = useForm(loginUserCallback, {
username: '',
password: ''
});
const [loginUser, { loading }] = useMutation(LOGIN_USER, {
update(
_,
{
data: { login: userData }
}
) {
context.login(userData);
props.history.push('/');
},
onError(err) {
setErrors(err.graphQLErrors[0].extensions.exception.errors);
},
variables: values
});
function loginUserCallback() {
loginUser();
}
return (
<div className="form-container">
<Form onSubmit={onSubmit} noValidate className={loading ? 'loading' : ''}>
<h1>Login</h1>
<Form.Input
label="Username"
placeholder="Username.."
name="username"
type="text"
value={values.username}
error={errors.username ? true : false}
onChange={onChange}
/>
<Form.Input
label="Password"
placeholder="Password.."
name="password"
type="password"
value={values.password}
error={errors.password ? true : false}
onChange={onChange}
/>
<Button type="submit" primary>
Login
</Button>
</Form>
{Object.keys(errors).length > 0 && (
<div className="ui error message">
<ul className="list">
{Object.values(errors).map((value) => (
<li key={value}>{value}</li>
))}
</ul>
</div>
)}
</div>
);
}
Example #9
Source File: CreateQuestion.js From graphql-sample-apps with Apache License 2.0 | 5 votes |
export default function CreateQuestion(props) {
const [title, setTitle] = useState("");
const [text, setText] = useState("");
const [tags, setTags] = useState([])
const history = useHistory();
const { user } = useAuth0();
let currentUser
if (user !== undefined) {
currentUser = {"username": user.email, "email": user.email}
}
const question = [{
title,
text,
tags,
author: currentUser,
datePublished: new Date().toISOString(),
likes: 0
}];
const handleChangeTags = (tagsSet) => {
setTags(tagsSet)
}
const [addQuestion] = useMutation(ADD_QUESTION)
return (
<div className="container">
<hr />
<div className="form-group">
<label htmlFor="questionTitle">Title:</label>
<input
id="questionTitle"
className="form-control"
value={title}
onChange={e => setTitle(e.target.value)}
type="text"
placeholder="Add Title"
/>
</div>
<div className="form-group">
<label htmlFor="questionTags">Tags:</label>
<TagsInput value={tags} onChange={handleChangeTags} />
</div>
<div className="form-group">
<label htmlFor="questionText">Text:</label>
<textarea
id="questionText"
className="form-control"
rows="15"
cols="100"
value={text}
onChange={e => setText(e.target.value)}
type="text"
placeholder="Add your question text"
/>
</div>
<button
type="submit"
className="btn btn-primary"
onClick={async e => {
e.preventDefault();
await addQuestion({ variables: {question}})
history.push("/");
}}
>
Publish
</button>
</div>
);
}
Example #10
Source File: EmailVerification.js From lifebank with MIT License | 5 votes |
EmailVerification = (props) => {
const { t } = useTranslation('translations')
const classes = useStyles()
const [, { logout }] = useUser()
const [validate, setValidate] = useState(true)
const { code } = useParams()
const history = useHistory()
const [
verifyEmail,
{ loading: loadingVerifyEmail, error: errorVerifyEmail, data: { verify_email: verifyEmailResult } = {} }
] = useMutation(VERIFY_EMAIL)
useEffect(() => {
verifyEmail({
variables: {
code: code
}
})
}, [verifyEmail, code])
useEffect(() => {
if (verifyEmailResult) setValidate(verifyEmailResult.is_verified)
}, [verifyEmailResult])
useEffect(() => {
if (errorVerifyEmail) {
if (errorVerifyEmail.message === 'GraphQL error: Could not verify JWT: JWTExpired') {
logout()
verifyEmail({
variables: {
code: code
}
})
} else {
setValidate(false)
history.push('/internal-error')
}
}
}, [verifyEmail, logout, code, history, errorVerifyEmail])
return (
<Box className={classes.root}>
<Grid container spacing={4}>
<Grid item xs={12} className={classes.content}>
<Box className={classes.centerText}>
{loadingVerifyEmail && <CircularProgress />}
{!loadingVerifyEmail && validate && (
<Typography className={classes.title}>
{t('emailVerification.emailVerified')}
</Typography>
)}
{!loadingVerifyEmail && !validate && (
<Typography className={classes.title}>
{t('emailVerification.somethingHappened')}
</Typography>
)}
{!loadingVerifyEmail && (
<Button
variant="contained"
color="secondary"
component={CustomRouterLink}
to="/"
className={classes.btnHome}
>
{t('emailVerification.takeHome')}
</Button>
)}
</Box>
</Grid>
</Grid>
</Box>
)
}
Example #11
Source File: DeleteButton.js From 0.4.1-Quarantime with MIT License | 5 votes |
function DeleteButton({ postId, commentId, callback }) {
const [confirmOpen, setConfirmOpen] = useState(false);
const mutation = commentId ? DELETE_COMMENT_MUTATION : DELETE_POST_MUTATION;
const [deletePostOrMutation] = useMutation(mutation, {
update(proxy) {
setConfirmOpen(false);
if (!commentId) {
const data = proxy.readQuery({
query: FETCH_POSTS_QUERY
});
data.getPosts = data.getPosts.filter((p) => p.id !== postId);
proxy.writeQuery({ query: FETCH_POSTS_QUERY, data });
}
if (callback) callback();
},
variables: {
postId,
commentId
}
});
return (
<>
<MyPopup content={commentId ? 'Delete comment' : 'Delete post'}>
<Button
as="div"
color="red"
floated="right"
onClick={() => setConfirmOpen(true)}
>
<Icon name="trash" style={{ margin: 0 }} />
</Button>
</MyPopup>
<Confirm
open={confirmOpen}
onCancel={() => setConfirmOpen(false)}
onConfirm={deletePostOrMutation}
/>
</>
);
}
Example #12
Source File: CancelEmailSubscription.js From lifebank with MIT License | 5 votes |
CancelEmailSubscription = () => {
const { t } = useTranslation('translations')
const classes = useStyles()
const { account } = useParams()
const [openSnackbar, setOpenSnackbar] = useState(false)
const handleOpenSnackbar = () => {
setOpenSnackbar(!openSnackbar)
}
const [
updateEmailSubscription,
{
loading: updateEmailSubscriptionLoading,
data: { update_user: updateEmailSubscriptionResult } = {}
}
] = useMutation(UPDATE_EMAIL_SUBSCRIPTION_MUTATION)
const onUpdateEmailSubscriptionClick = () => {
updateEmailSubscription({
variables: {
account,
state: false
}
})
}
useEffect(() => {
if (updateEmailSubscriptionResult && updateEmailSubscriptionResult.affected_rows === 0) handleOpenSnackbar()
}, [handleOpenSnackbar, updateEmailSubscriptionResult])
return (
<Box className={classes.root}>
<Grid container spacing={4}>
<Grid item xs={12} className={classes.content}>
<Box className={classes.centerText}>
{updateEmailSubscriptionLoading && <CircularProgress />}
{!updateEmailSubscriptionLoading && !updateEmailSubscriptionResult && (
<Typography className={classes.title}>
{t('emailSubscription.cancelMessage')}
</Typography>
)}
{!updateEmailSubscriptionLoading && updateEmailSubscriptionResult && (
<Typography className={classes.title}>
{t('emailSubscription.successfulCancel')}
</Typography>
)}
{!updateEmailSubscriptionLoading && !updateEmailSubscriptionResult && (
<Button
variant="contained"
color="secondary"
onClick={onUpdateEmailSubscriptionClick}
className={classes.btnHome}
>
{t('emailSubscription.cancel')}
</Button>
)}
{!updateEmailSubscriptionLoading && updateEmailSubscriptionResult && (
<Button
variant="contained"
color="secondary"
component={CustomRouterLink}
to="/"
className={classes.btnHome}
>
{t('emailVerification.takeHome')}
</Button>
)}
</Box>
</Grid>
</Grid>
<Snackbar open={openSnackbar} autoHideDuration={4000} onClose={handleOpenSnackbar}>
<Alert severity="error">
{t('emailSubscription.error')}
</Alert>
</Snackbar>
</Box>
)
}
Example #13
Source File: DetailPage.js From mongodb-graphql-demo with Apache License 2.0 | 5 votes |
function DetailPage(props) {
const [deletePost] = useMutation(DELETE_INSTAPOST);
const { instapost } = props;
return (
<Modal
isOpen
ariaHideApp={false}
contentLabel="Create Post"
style={detailModalStyle}
onRequestClose={props.history.goBack}
>
<div
className="close fixed right-0 top-0 pointer"
onClick={props.history.goBack}
>
<img src={require('../assets/close.svg')} alt="" />
</div>
<div
className="delete ttu white pointer fw6 absolute left-0 top-0 br2"
onClick={e => {
deletePost({
variables: {
data: {
_id: instapost._id,
},
},
});
props.history.replace('/');
}}
>
Delete
</div>
<div className="bg-white detail flex flex-column no-underline br2 h-100">
<div
className="image"
style={{
backgroundImage: `url(${instapost.imageUrl})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
paddingBottom: '100%',
}}
/>
<div className="flex items-center black-80 fw3 description">
{instapost.description}
</div>
</div>
</Modal>
);
}
Example #14
Source File: GithubAuth.js From pathways with GNU General Public License v3.0 | 5 votes |
GithubAuth = (props) => {
const [isTouched, isTouchedHandler] = useState(false);
const [getToken, { loading, data }] = useMutation(GET_TOKEN);
let display = <Container>
<Header>
<div style={{ display: "flex", alignItems: "center" }}>
<Logo />
<Logotype />
</div>
<a href={`https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&scope=user`}>
Login
</a>
</Header>
</Container>
let displayedData = null;
let code = null;
code = decodeURIComponent(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURIComponent('code').replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
if (code && !isTouched) {
isTouchedHandler(true);
getToken({ variables: { code: code } })
}
if(!isTouched){
displayedData = null;
}
else{
if (loading) {
displayedData = <div>Loading ...</div>
}
else {
let token = data.GithubAuth.token;
displayedData = <div>Your Token is <br />{token}</div>
}
}
return (
<div>
{display}
<div>{displayedData}</div>
</div>
);
}
Example #15
Source File: NotificationStructure.js From lifebank with MIT License | 5 votes |
NotificationStructure = ({ id, title, description, state, dateAndTime }) => {
const classes = useStyles()
const [name, setName] = useState()
const [time, setTime] = useState()
const { refetch: getData } = useQuery(GET_ACCOUNT_NAME, {
variables: {
account: description.substring(5, 17)
},
skip: true
})
const [editNotificationState, { }] = useMutation(EDIT_NOTIFICATION_STATE)
useEffect(() => {
const response = async () => {
const { data } = await getData({ account: description.substring(5, 17) })
setName(data.user[0].name)
}
response()
}, [description])
useEffect(() => {
const hour = parseInt(dateAndTime.substring(11, 13)) - 6
setTime(hour.toString() + dateAndTime.substring(13, 19))
}, [dateAndTime])
const changeNotificationState = () => {
editNotificationState({
variables: {
id: id
}
})
}
return (
<>
<Button className={classes.wrapper} onMouseOver={changeNotificationState}>
<Grid container xs={3}>
<Grid item xs={12}>
{state === true && (
<NewNotificationIcon className={classes.iconOption} />
)}
</Grid>
</Grid>
<Grid container xs={11}>
<Grid item xs={12}>
<Typography className={classes.title}>
{title}
</Typography>
</Grid>
<Grid item xs={10}>
<Typography className={classes.labelOption}>
{description.replace(description.substring(5, 17), name)}
</Typography>
</Grid>
</Grid>
<Grid container xs={6}>
<Grid item xs={12}>
<Typography className={classes.labelOption}>
{time}
<br ></br>
{dateAndTime.substring(5, 10) + "-" + dateAndTime.substring(0, 4)}
</Typography>
</Grid>
</Grid>
</Button>
</>
)
}
Example #16
Source File: Header.js From pathways with GNU General Public License v3.0 | 5 votes |
Header = (props) => {
const [isLoggedIn, isLoggedInHandler] = useState(false)
const [isTouched, isTouchedHandler] = useState(false)
const [getToken, { loading, data }] = useMutation(GET_TOKEN)
let code = null
code = decodeURIComponent(
window.location.search.replace(
new RegExp(
"^(?:.*[&\\?]" +
encodeURIComponent("code").replace(/[\.\+\*]/g, "\\$&") +
"(?:\\=([^&]*))?)?.*$",
"i"
),
"$1"
)
)
let token
if (code && !isLoggedIn) {
console.log(code);
isLoggedInHandler(true)
getToken({ variables: { code: code } })
}
if (data && !isTouched) {
isTouchedHandler(true)
token = data.GithubAuth.token
console.log(token, data);
props.userLogin(null);
localStorage.setItem("token", token)
alert("You are logged in !!!")
}
return (
<React.Fragment>
<Navbar className={classes.navbar}>
<Nav className={classes.navlinks}>
<Nav.Link
href={`https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&scope=user`}
>
<div className={classes.login}>
<LogoGithub fontSize="35px" color="white" />
<div className={classes.text}>
Login with GitHub
</div>
</div>
</Nav.Link>
</Nav>
</Navbar>
</React.Fragment>
)
}
Example #17
Source File: ForgotPassword.jsx From saasgear with MIT License | 5 votes |
function ForgotPassword() {
useDocumentHeader({ title: 'Forgot password' });
const [isSubmitted, setIsSubmitted] = useState(false);
const { register, handleSubmit, errors } = useForm({
resolver: yupResolver(ForgotPasswordSchema),
});
const [forgotPasswordMutation, { loading, error }] = useMutation(
forgotpasswordQuery,
);
async function onSubmit(data) {
setIsSubmitted(false);
try {
await forgotPasswordMutation({ variables: data });
setIsSubmitted(true);
} catch (e) {
console.log(e);
setIsSubmitted(false);
}
}
return (
<ForgotPasswordWrapper>
<Overlay />
<ForgotPasswordContainer>
<ForgotPasswordForm
onSubmit={handleSubmit(onSubmit)}
register={register}
errors={errors}
isSubmitted={isSubmitted && !error}
isSubmitting={loading}
apiError={error?.message}
/>
<SquareIconTop>
<img src={squareRadiusTop} alt="" />
</SquareIconTop>
<SmallSquareBottom>
<img src={squareRadiusTopPrimary} alt="" />
</SmallSquareBottom>
<SmallSquareTop>
<img src={squareRadiusTopPrimarySmall} alt="" />
</SmallSquareTop>
<SmallSquareGrid>
<img src={squareGrid} alt="" />
</SmallSquareGrid>
<SquareIconBottom>
<img src={squareRadiusTopBig} alt="" />
</SquareIconBottom>
<CircleIcon>
<img src={circleSmall} alt="" />
</CircleIcon>
</ForgotPasswordContainer>
</ForgotPasswordWrapper>
);
}
Example #18
Source File: TodoApp.js From graphql-sample-apps with Apache License 2.0 | 4 votes |
export default function TodoApp() {
const [nowShowing, setNowShowing] = useState(defs.ALL_TODOS);
const [getEditing, setEditing] = useState(null);
const [newTodo, setNewTodo] = useState("");
const [addTodo] = useMutation(ADD_TODO);
const [toggleTodo] = useMutation(TOGGLE_TODO);
const [toggleAllTodo] = useMutation(TOGGLE_ALL_TODO);
const [deleteTodo] = useMutation(DELETE_TODO);
const [updateTodo] = useMutation(UPDATE_TODO);
const [clearCompletedTodo] = useMutation(CLEAR_COMPLETED_TODO);
const [shownTodos, setShownTodos] = useState([]);
const { loading, error, data } = useQuery(GET_TODOS);
const getData = () => {
if (loading || !data) {
return null
}
if (error) {
alert(`Error: ${error}`);
return `Error: ${error.message}`;
}
setShownTodos(data.queryTask)
}
useEffect(() => {
const setNowShowingFn = nowShowing => () => setNowShowing(nowShowing)
const routes = {
'/': setNowShowingFn(defs.ALL_TODOS),
'/active': setNowShowingFn(defs.ACTIVE_TODOS),
'/completed': setNowShowingFn(defs.COMPLETED_TODOS),
}
const processLocationHash = hash => {
if (hash) {
hash = hash.substring(1)
}
const route = routes[hash] || routes['/']
route()
}
processLocationHash(history.location.hash)
history.listen((location, action) =>
processLocationHash(location.hash)
)
getData()
})
const handleChange = event => {
setNewTodo(event.target.value)
}
const handleNewTodoKeyDown = event => {
if (event.keyCode !== ENTER_KEY) {
return
}
event.preventDefault()
const val = newTodo
if (val) {
add(val)
setNewTodo('')
}
}
const add = async (title) => {
await addTodo({
variables: { task: [
{ title: title, completed: false }
]},
refetchQueries: [{
query: GET_TODOS
}]
});
}
const destroy = todo =>
deleteTodo({
variables: {
taskID: [todo.id]
},
refetchQueries: [{
query: GET_TODOS
}]
})
const toggleAll = event => {
const checked = event.target.checked
toggleAllTodo({
variables: {
completed: checked
},
refetchQueries: [{
query: GET_TODOS
}]
})
}
const toggle = todoToToggle => {
toggleTodo({
variables: {
taskID: todoToToggle.id,
completed: !todoToToggle.completed
},
refetchQueries: [{
query: GET_TODOS
}]
})
}
const edit = todo => setEditing(todo.id)
const save = (todoToSave, text) => {
updateTodo({
variables: {
taskID: todoToSave.id,
task: {
title: text
},
refetchQueries: [{
query: GET_TODOS
}]
}
})
setEditing(null)
}
const cancel = () =>
setEditing(null)
const clearCompleted = () =>
clearCompletedTodo({
variables: {
completed: true
},
refetchQueries: [{
query: GET_TODOS
}]
})
const newTodos = shownTodos.filter(todo => {
switch (nowShowing) {
case defs.ACTIVE_TODOS:
return !todo.completed
case defs.COMPLETED_TODOS:
return todo.completed
default:
return true
}
})
const todoItems = newTodos.map(todo => {
return (
<TodoItem
key={todo.id}
todo={todo}
onToggle={() => toggle(todo)}
onDestroy={() => destroy(todo)}
onEdit={() => edit(todo)}
editing={getEditing === todo.id}
onSave={text => save(todo, text)}
onCancel={cancel}
/>
)
})
const activeTodoCount = shownTodos.reduce(function (accum, todo) {
return todo.completed ? accum : accum + 1
}, 0)
const completedCount = shownTodos.length - activeTodoCount
const footer = (activeTodoCount || completedCount)
? <TodoFooter
count={activeTodoCount}
completedCount={completedCount}
nowShowing={nowShowing}
onClearCompleted={clearCompleted}
/>
: null
const main = !shownTodos.length
? null
: (
<section className="main">
<input
id="toggle-all"
className="toggle-all"
type="checkbox"
onChange={toggleAll}
checked={activeTodoCount === 0}
/>
<label
htmlFor="toggle-all"
/>
<ul className="todo-list">
{todoItems}
</ul>
</section>
)
return (
<div>
<header className="header">
<h1>todos</h1>
<input
className="new-todo"
placeholder="What needs to be done?"
value={newTodo}
onKeyDown={handleNewTodoKeyDown}
onChange={handleChange}
autoFocus={true}
/>
</header>
{main}
{footer}
</div>
)
}
Example #19
Source File: PodWithdrawPendingForm.jsx From pods-frontend with MIT License | 4 votes |
export function PodWithdrawPendingForm({ podAddress, userAddress }) {
const [
amount,
setAmount
] = useState('')
const [
lastRefetchTxId,
setLastRefetchTxId
] = useState(0)
const weiAmount = ethers.utils.parseEther(amount || '0')
let podUser = useQuery(podUserQuery, {
variables: { podAddress, userAddress },
skip: !userAddress || !podAddress
})
let transactions = useQuery(transactionsQuery)
let loading = podUser.loading || transactions.loading
let error = podUser.error || transactions.error
const [withdrawPending, withdrawPendingResult] = useMutation(gql`
mutation withdrawPendingMutation($podAddress: String!, $amount: Float!) {
sendTransaction(abi: "Pod", address: $podAddress, fn: "withdrawPendingDeposit", params: [$amount, "0x0"], gasLimit: 800000) @client
}
`, {
variables: {
podAddress,
amount: weiAmount
},
refetchQueries: ['transactionsQuery']
})
let withdrawPendingTx
if (!loading && !error && withdrawPendingResult.data) {
withdrawPendingTx = transactions.data._transactions.find(tx => tx.id === withdrawPendingResult.data.sendTransaction.id)
}
if (withdrawPendingTx && withdrawPendingTx.completed && withdrawPendingTx.id > lastRefetchTxId) {
setAmount(0)
podUser.refetch()
setLastRefetchTxId(withdrawPendingTx.id)
}
let sufficientBalance = false
if (!loading && !error && podUser.data) {
sufficientBalance = podUser.data.pendingDeposit.gte(ethers.utils.bigNumberify(weiAmount))
}
return (
<form className="w-full max-w-sm mt-5" onSubmit={(e) => { e.preventDefault(); withdrawPending(); } }>
<div className="md:flex md:items-center mb-3">
<div className="md:w-1/3">
<label className="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" htmlFor="inline-full-name">
Withdraw Pending Deposit
</label>
</div>
<div className="md:w-2/3">
<input
className="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
id="inline-full-name"
type="text"
placeholder="enter Dai amount"
value={amount}
onChange={(e) => { e.preventDefault(); setAmount(e.target.value) } }
/>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3"></div>
<div className="md:w-2/3">
<Button
disabled={!sufficientBalance}
onClick={(e) => { e.preventDefault(); withdrawPending(); } }>
Withdraw Pending
</Button>
</div>
</div>
</form>
)
}
Example #20
Source File: Signup.js From lifebank with MIT License | 4 votes |
Signup = ({ isHome, isModal, isSideBar, onCloseSignUp }) => {
const { t } = useTranslation('translations')
const classes = useStyles()
const [user, setUser] = useReducer(
(user, newUser) => ({ ...user, ...newUser }),
{}
)
const [activeStep, setActiveStep] = useState(0)
const [role, setRole] = useState()
const [currentUser, { login }] = useUser()
const [open, setOpen] = useState(!!isModal)
const [openSnackbar, setOpenSnackbar] = useState(false)
const [maxWidth] = useState('md')
const theme = useTheme()
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const [isEmailValid, setEmailValid] = useState(false)
const [checkEmailLoading, setcheckEmailLoaded] = useState(false)
const handleOpen = () => {
setOpen(!open)
if (onCloseSignUp) {
onCloseSignUp()
}
}
const handleOpenAlert = () => {
setOpenSnackbar({ ...openSnackbar, show: false })
}
const [
createAccount,
{
error: errorcreateAccount,
loading: createAccountLoading,
data: { create_account: createAccountResult } = {}
}
] = useMutation(CREATE_ACCOUNT_MUTATION)
const [
createAccountAuth,
{
error: errorcreateAccountAuth,
loading: createAccountLoadingAuth,
data: { create_account_auth: createAccountResultAuth } = {}
}
] = useMutation(CREATE_ACCOUNT_AUTH_MUTATION)
const [
preRegisterLifebank,
{
error: errorpreRegisterLifebank,
loading: preRegisterLifebankLoading,
data: { create_pre_register_lifebank: preRegisterLifebankResult } = {}
}
] = useMutation(CREATE_PRE_REGITER_LIFEBANK_MUTATION)
const handleRoleChange = (role) => {
setRole(role)
setActiveStep(activeStep + 1)
}
const handleSetField = useCallback((field, value) => {
setUser({ [field]: value })
}, [])
const handleGoBack = () => {
activeStep && setActiveStep(activeStep - 1)
handleSetField('email', ' ')
}
const handleCreateAccount = () => {
const { email, name, passwordPlainText } = user
createAccount({
variables: {
role,
email,
emailContent: {
subject: t('emailMessage.subjectVerificationCode'),
title: t('emailMessage.titleVerificationCode'),
message: t('emailMessage.messageVerificationCode'),
button: t('emailMessage.verifyButton')
},
name: name || t('signup.defaultUsername'),
passwordPlainText,
signup_method: 'lifebank'
}
})
}
const handleCreateAccountWithAuth = async (status, email, name, passwordPlainText, signupMethod) => {
if (status) {
const { data } = await checkEmail({ email: email })
if (data.user.length === 0) {
createAccountAuth({
variables: {
role,
email,
emailContent: {
subject: t('emailMessage.subjectVerificationCode'),
title: t('emailMessage.titleVerificationCode'),
message: t('emailMessage.messageVerificationCode'),
button: t('emailMessage.verifyButton')
},
name,
passwordPlainText,
signup_method: signupMethod
}
})
} else {
setOpenSnackbar({
show: true,
message: t('errors.authError'),
severity: 'error'
})
}
}
}
const handlePreRegisterLifebank = () => {
const {
email,
password,
name,
address,
phone,
description,
coordinates,
requirement
} = user
let { immunity_test, invitation_code, urgency_level } = user
if (immunity_test === undefined) immunity_test = false
if (invitation_code === undefined || !invitation_code) invitation_code = ' '
if (urgency_level === undefined) urgency_level = 1
const schedule = '[]'
preRegisterLifebank({
variables: {
email,
emailContent: {
subject: t('emailMessage.subjectVerificationCode'),
title: t('emailMessage.titleVerificationCode'),
message: t('emailMessage.messageVerificationCode'),
button: t('emailMessage.verifyButton')
},
passwordPlainText: password,
name,
address,
schedule,
phone,
description,
urgency_level,
coordinates,
immunity_test,
invitation_code,
requirement
}
})
}
const { refetch: checkEmail } = useQuery(VALIDATION_EMAIL, {
variables: {
email: user.email
},
skip: true
})
useEffect(() => {
const regularExpresion = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
const validEmail = async () => {
const { data } = await checkEmail({
email: user.email
})
if (data) {
data.preregister_lifebank.length === 0 && data.user.length === 0
? setEmailValid(true)
: setEmailValid(false)
setcheckEmailLoaded(true)
}
}
if (regularExpresion.test(user?.email)) {
validEmail()
} else {
setEmailValid(false)
setcheckEmailLoaded(false)
}
}, [user, checkEmail])
useEffect(() => {
if (preRegisterLifebankResult) {
handleOpen()
setOpenSnackbar({
show: true,
message: t('signup.sucessfulPreregistration'),
severity: 'success'
})
}
}, [t, preRegisterLifebankResult])
useEffect(() => {
if (createAccountResult) {
handleOpen()
setOpenSnackbar({
show: true,
message: t('signup.sucessfulRegistration'),
severity: 'success'
})
}
}, [t, createAccountResult])
useEffect(() => {
if (createAccountResultAuth) {
handleOpen()
setOpenSnackbar({
show: true,
message: t('signup.sucessfulRegistration'),
severity: 'success'
})
login(createAccountResultAuth.token)
}
}, [t, login, createAccountResultAuth])
useEffect(() => {
if (errorcreateAccount) setOpenSnackbar({
show: true,
message: t('errors.authError'),
severity: 'error'
})
}, [t, errorcreateAccount])
useEffect(() => {
if (errorcreateAccountAuth) setOpenSnackbar({
show: true,
message: t('errors.authError'),
severity: 'error'
})
}, [t, errorcreateAccountAuth])
useEffect(() => {
if (errorpreRegisterLifebank) setOpenSnackbar({
show: true,
message: t('errors.authError'),
severity: 'error'
})
}, [t, errorpreRegisterLifebank])
useEffect(() => {
if (open) {
handleSetField('email', ' ')
setActiveStep(0)
}
}, [open])
return (
<Box className={classes.dialog}>
{isHome && !currentUser &&
<Button color="secondary" className={classes.registerBtn} onClick={handleOpen}>
{t('signup.register')}
</Button>
}
{isSideBar && !currentUser &&
<Box
className={classes.registerBtnSideBar}
onClick={handleOpen}
>
<ContactMailIcon className={classes.iconOption} />
<Link to="/">
<Typography
variant="body1"
className={classes.labelOption}
>
{t('signup.register')}
</Typography>
</Link>
</Box>
}
<Dialog
fullScreen={fullScreen}
maxWidth={maxWidth}
open={open}
onClose={handleOpen}
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<DialogContent className={classes.dimensions} >
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
onClick={handleOpen}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
{activeStep !== 0 && (
<Box className={classes.goBack}>
<IconButton aria-label="go-back" onClick={handleGoBack}>
<ArrowBackIcon color="primary" />
</IconButton>
</Box>
)}
<Box className={classes.register}>
<Box className={classes.stepperContent}>
{activeStep === 0 && (
<>
<Typography className={classes.titleRegisterRoleSelector}>{t('signup.register')}</Typography>
<Typography className={classes.registerText}>{t('signup.registerText')}</Typography>
<SignupRoleSelector onSubmit={handleRoleChange} />
</>
)}
{activeStep === 1 && role === 'donor' && (
<>
<Typography className={classes.titleRegister}>{t('signup.asAdonor')}</Typography>
<Typography className={classes.text}>{t('signup.allYouNeed')}</Typography>
<Suspense fallback={<CircularProgress />}>
<SignupDonor
onSubmit={handleCreateAccount}
onSubmitWithAuth={handleCreateAccountWithAuth}
loading={createAccountLoading || createAccountLoadingAuth}
setField={handleSetField}
isEmailValid={isEmailValid}
>
<ValidateEmail
isValid={isEmailValid}
loading={checkEmailLoading}
setField={handleSetField}
user={user}
/>
</SignupDonor>
</Suspense>
</>
)}
{activeStep === 1 && role === 'sponsor' && (
<>
<Typography className={classes.titleRegister}>{t('signup.asAsponsor')}</Typography>
<Typography className={classes.text}>{t('signup.allYouNeed')}</Typography>
<Suspense fallback={<CircularProgress />}>
<SimpleRegisterForm
onSubmit={handleCreateAccount}
loading={createAccountLoading}
setField={handleSetField}
isEmailValid={isEmailValid}
>
<ValidateEmail
isValid={isEmailValid}
loading={checkEmailLoading}
user={user}
setField={handleSetField}
/>
</SimpleRegisterForm>
</Suspense>
</>
)}
{activeStep === 1 && role === 'lifebank' && (
<>
<Typography className={classes.titleRegister}>{t('signup.asAbank')}</Typography>
<Typography variant="body1" className={classes.text}>{t('signup.preRegistrationRequirement')}</Typography>
<Suspense fallback={<CircularProgress />}>
<SignupLifeBank
onSubmit={handlePreRegisterLifebank}
loading={preRegisterLifebankLoading}
setField={handleSetField}
user={user}
isEmailValid={isEmailValid}
>
<ValidateEmail
isValid={isEmailValid}
loading={checkEmailLoading}
user={user}
setField={handleSetField}
/>
</SignupLifeBank>
</Suspense>
</>
)}
</Box>
</Box>
</DialogContent>
</Dialog>
<Snackbar open={openSnackbar.show} autoHideDuration={4000} onClose={handleOpenAlert}>
<Alert severity={openSnackbar.severity}>
{openSnackbar.message}
</Alert>
</Snackbar>
</Box>
)
}
Example #21
Source File: PodRedeemToPoolForm.jsx From pods-frontend with MIT License | 4 votes |
export function PodRedeemToPoolForm({ podAddress, userAddress }) {
const [
amount,
setAmount
] = useState('')
const [
lastRefetchTxId,
setLastRefetchTxId
] = useState(0)
const weiAmount = ethers.utils.parseEther(amount || '0')
let podUser = useQuery(podUserQuery, {
variables: { podAddress, userAddress },
skip: !userAddress || !podAddress
})
let transactions = useQuery(transactionsQuery)
let loading = podUser.loading || transactions.loading
let error = podUser.error || transactions.error
const [redeemToPool, redeemToPoolResult] = useMutation(gql`
mutation redeemToPoolMutation($podAddress: String!, $amount: Float!) {
sendTransaction(abi: "Pod", address: $podAddress, fn: "redeemToPool", params: [$amount, "0x0"], gasLimit: 1000000) @client
}
`, {
variables: {
podAddress,
amount: weiAmount
},
refetchQueries: ['transactionsQuery']
})
let redeemToPoolTx
if (!loading && !error && redeemToPoolResult.data) {
redeemToPoolTx = transactions.data._transactions.find(tx => tx.id === redeemToPoolResult.data.sendTransaction.id)
}
if (redeemToPoolTx && redeemToPoolTx.completed && redeemToPoolTx.id > lastRefetchTxId) {
setAmount(0)
podUser.refetch()
setLastRefetchTxId(redeemToPoolTx.id)
}
let sufficientBalance = false
if (!loading && !error && podUser.data) {
sufficientBalance = podUser.data.balance.gte(ethers.utils.bigNumberify(weiAmount))
}
return (
<form className="w-full max-w-sm mt-5" onSubmit={(e) => { e.preventDefault(); redeemToPool() } }>
<div className="md:flex md:items-center mb-3">
<div className="md:w-1/3">
<label className="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" htmlFor="inline-full-name">
Redeem to Pool
</label>
</div>
<div className="md:w-2/3">
<input
className="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
id="inline-full-name"
type="text"
placeholder="enter Pod token amount"
value={amount}
onChange={(e) => { e.preventDefault(); setAmount(e.target.value) } }
/>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3"></div>
<div className="md:w-2/3">
<Button
disabled={!sufficientBalance}
onClick={(e) => { e.preventDefault(); redeemToPool(); } }>
Redeem to Pool
</Button>
</div>
</div>
</form>
)
}
Example #22
Source File: GenericOfferFormComponent.js From lifebank with MIT License | 4 votes |
GenericOfferFormComponent = ({
open,
setOpen,
sponsor_id,
isEditing,
setOffers,
data,
offerNotification
}) => {
const { t } = useTranslation('translations')
const classes = useStyles()
const theme = useTheme()
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const [disableUrlInput, setDisableUrlInput] = useState(true)
const imgUrlValueRef = useRef(undefined)
const [offer, setOffer] = useState()
const [alignment, setAlignment] = useState('LocalOfferIcon')
const [updatedOffer, setUpdatedOffer] = useState()
const [openSnackbar, setOpenSnackbar] = useState({
show: false,
message: '',
severity: 'success'
})
const [
createOffer,
{
loading: createOfferLoading,
data: { insert_offer_one: createOfferResult } = {}
}
] = useMutation(CREATE_OFFER_MUTATION)
const [
updateOffer,
{
loading: updateOfferLoading,
data: { update_offer: updateOfferResult } = {}
}
] = useMutation(UPDATE_OFFER_MUTATION)
const handleSubmit = () => {
const {
offer_type,
online_only,
description,
limited,
quantity,
start_date,
end_date,
offer_name,
id,
active,
cost_in_tokens,
icon
} = offer
const images = JSON.stringify(offer.images)
if (!isEditing)
createOffer({
variables: {
offer_type,
online_only: online_only || false,
description,
limited,
quantity: quantity || undefined,
start_date: start_date || undefined,
end_date: end_date || undefined,
cost_in_tokens,
images,
sponsor_id,
active: true,
offer_name: offer_name,
icon: icon || 'LocalOfferIcon'
}
})
else {
updateOffer({
variables: {
offer_type,
online_only,
description,
limited,
quantity: quantity || undefined,
start_date: start_date || undefined,
end_date: end_date || undefined,
cost_in_tokens,
images,
offer_name,
id,
icon,
active
}
})
setUpdatedOffer({
offer_type,
online_only,
description,
limited,
quantity: quantity || undefined,
start_date: start_date || undefined,
end_date: end_date || undefined,
cost_in_tokens,
images,
offer_name,
id,
icon,
active
})
}
}
const handleAlignment = (event, newAlignment) => {
setOffer({ ...offer, icon: newAlignment })
setAlignment(newAlignment)
}
useEffect(() => {
if (data) {
data.images = JSON.parse(data.images)
setOffer(data)
} else
setOffer({
limited: true,
images: [],
online_only: true
})
}, [data])
useEffect(() => {
if (updateOfferResult) {
setOpenSnackbar({
show: true,
message: t('offersManagement.offerUpdatedMessage'),
severity: 'success'
})
setOffers((offs) =>
offs.map((offr) => {
if (offr.id === updatedOffer.id) offr = updatedOffer
return offr
})
)
}
}, [t, updateOfferResult])
useEffect(() => {
if (createOfferResult) {
setOpenSnackbar({
show: true,
message: t('offersManagement.offerCreatedMessage'),
severity: 'success'
})
setOffers((offs) => [...offs, createOfferResult])
}
}, [t, createOfferResult])
function executeAddImage(e) {
if (e.key === 'Enter' && (!disableUrlInput)) {
e.preventDefault()
setOffer({
...offer,
images: offer.images.concat(imgUrlValueRef.current.value)
})
imgUrlValueRef.current.value = ''
setDisableUrlInput(true)
}
}
return (
<Dialog
fullScreen={fullScreen}
open={open}
onClose={() => setOpen(false)}
TransitionComponent={Transition}
>
<Box className={classes.dialog}>
{fullScreen &&
< AppBar className={classes.appBar} >
<Toolbar>
<IconButton
className={classes.backIcon}
onClick={() => setOpen(false)}
aria-label="close"
>
<KeyboardBackspaceIcon />
</IconButton>
<Typography variant="h1" className={classes.titleAppBar}>
{t('offersManagement.addOffer')}
</Typography>
</Toolbar>
</AppBar>
}
{!fullScreen &&
<Box>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={() => setOpen(false)}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
<Typography className={classes.titleModal}>
{t('offersManagement.addOffer')}
</Typography>
</Box>
}
{
offer && (
<form autoComplete="off" className={classes.form}>
<TextField
id="offer-name"
label={t('offersManagement.offerName')}
variant="outlined"
value={offer.offer_name || undefined}
fullWidth
onChange={(event) =>
setOffer({ ...offer, offer_name: event.target.value })
}
className={classes.textField}
/>
<FormControl variant="outlined" className={classes.textField}>
<InputLabel id="bussines-type-label">
{t('offersManagement.selectOfferType')}
</InputLabel>
<Select
labelId="offer-type-label"
id="offer-type"
label={t('offersManagement.selectOfferType')}
value={offer.offer_type || ''}
onChange={(event) =>
setOffer({ ...offer, offer_type: event.target.value })
}
>
<MenuItem value="discount">{t('categories.discount')}</MenuItem>
<MenuItem value="freeProduct">{t('categories.freeProduct')}</MenuItem>//
<MenuItem value="coupon">{t('categories.coupon')}</MenuItem>
<MenuItem value="badge">{t('categories.badge')}</MenuItem>//
<MenuItem value="benefit">{t('categories.benefit')}</MenuItem>
</Select>
</FormControl>
<TextField
id="offer-description"
label={t('offersManagement.offerDescription')}
variant="outlined"
value={offer.description || undefined}
fullWidth
onChange={(event) =>
setOffer({ ...offer, description: event.target.value })
}
className={classes.textField}
/>
<TextField
id="cost-in-tokens"
label={t('offersManagement.costInTokens')}
variant="outlined"
onKeyDown={(evt) => evt.key === 'e' && evt.preventDefault()}
value={offer.cost_in_tokens || undefined}
fullWidth
InputProps={{
inputComponent: NumberFormatCustom,
}}
onChange={(event) =>
setOffer({ ...offer, cost_in_tokens: event.target.value })
}
className={classes.textField}
/>
<Divider className={classes.divider} />
<Typography className={classes.boldText} variant="subtitle1">{t('offersManagement.chooseIcon')}</Typography>
<ToggleButtonGroup
id="offer-icon"
value={offer.icon || alignment}
exclusive
onChange={handleAlignment}
aria-label="text alignment"
className={classes.toggleIcons}
>
<ToggleButton value="LocalOfferIcon" className={classes.offerIcon}><LocalOfferIcon /></ToggleButton>
<ToggleButton value="CardGiftcardIcon" className={classes.offerIcon} ><CardGiftcardIcon /></ToggleButton>
<ToggleButton value="StarsIcon" className={classes.offerIcon}><StarsIcon /></ToggleButton>
<ToggleButton value="WhatshotIcon" className={classes.offerIcon}><WhatshotIcon /></ToggleButton>
<ToggleButton value="AccessTimeIcon" className={classes.offerIcon}><AccessTimeIcon /></ToggleButton>
<ToggleButton value="StorefrontIcon" className={classes.offerIcon}><StorefrontIcon /></ToggleButton>
<ToggleButton value="TagFacesIcon" className={classes.offerIcon}><TagFacesIcon /></ToggleButton>
<ToggleButton value="ShoppingBasketIcon" className={classes.offerIcon}><ShoppingBasketIcon /></ToggleButton>
<ToggleButton value="RestaurantIcon" className={classes.offerIcon}><RestaurantIcon /></ToggleButton>
<ToggleButton value="FilterVintageIcon" className={classes.offerIcon}><FilterVintageIcon /></ToggleButton>
<ToggleButton value="OutdoorGrillIcon" className={classes.offerIcon}><OutdoorGrillIcon /></ToggleButton>
<ToggleButton value="OfflineBoltIcon" className={classes.offerIcon}><OfflineBoltIcon /></ToggleButton>
</ToggleButtonGroup>
<Divider className={classes.divider} />
<Typography className={classes.boldText} variant="subtitle1">{t('offersManagement.redeemAvailability')}</Typography>
<FormControl component="fieldset" className={classes.radioGroup}>
<RadioGroup
aria-label="limitation"
value={String(offer.limited) || undefined}
onChange={(event) => {
setOffer({ ...offer, limited: event.target.value })
}}
>
<FormControlLabel
value="false"
control={<Radio />}
label={t('offersManagement.unlimited')}
/>
<FormControlLabel
value="true"
control={<Radio />}
label={t('offersManagement.limited')}
/>
</RadioGroup>
{(offer.limited === true || offer.limited === 'true') && (
<LimitationHandling
setQuantity={(val) => setOffer({ ...offer, quantity: val })}
initialDates={[offer.start_date, offer.end_date]}
fullWidth
setDates={(dates) =>
setOffer({
...offer,
start_date: dates[0],
end_date: dates[1]
})
}
classes={classes}
/>
)}
</FormControl>
<Divider className={classes.divider} />
<Typography className={classes.boldText} variant="subtitle1">{t('profile.images')}</Typography>
<TextField
id="image-url"
label={t('offersManagement.imageUrl')}
variant="outlined"
fullWidth
inputRef={imgUrlValueRef}
onChange={(e) => setDisableUrlInput(e.target.value.length < 1)}
className={classes.textField}
onKeyPress={(event) =>
executeAddImage(event)
}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
color="secondary"
aria-label="add photo url"
disabled={disableUrlInput}
onClick={() => {
setOffer({
...offer,
images: offer.images.concat(imgUrlValueRef.current.value)
})
imgUrlValueRef.current.value = ''
setDisableUrlInput(true)
}}
>
<AddIcon />
</IconButton>
</InputAdornment>
)
}}
/>
<Box className={classes.addButtonContainer}>
{offer.images.length < 1 &&
<Typography variant="caption">
{t('offersManagement.imageRestriction')}
</Typography>
}
</Box>
{offer.images.length > 0 && (
<>
{offer.images &&
<Box className={classes.carrouselContainer}>
<CarouselComponent
deleteItem={(url) => {
setOffer({
...offer,
images: offer.images.filter((p) => p !== url)
})
}}
activeDeletion
images={offer.images} />
</Box>
}
</>
)}
<Box
style={{ marginTop: '50px' }}
>
<Button
className={classes.saveBtn}
disabled={
createOfferLoading ||
updateOfferLoading ||
!offer.description ||
!offer.offer_type ||
!offer.cost_in_tokens ||
offer.images.length < 1
}
onClick={() => {
handleSubmit()
offerNotification()
setOpen(false)
}}
variant="contained"
color="primary"
>
{t('offersManagement.addOffer')}
</Button>
</Box>
</form>
)
}
</Box>
</Dialog >
)
}
Example #23
Source File: useTokenEntity.js From feedadoc with MIT License | 4 votes |
useTokenEntity = (token, entityType) => {
const entityMutation = getMutationByEntityType(entityType);
const { error, data } = useQuery(GET_ENTITY_BY_TOKEN, {
variables: { token },
});
const [saveEntity, { error: savingError, data: saveData }] = useMutation(
entityMutation
);
const [entity, setEntity] = useState();
const [requestState, setRequestState] = useState(
TOKEN_ENTITY_REQUEST_STATES.LOADING
);
const [isSaveSnackbarOpen, setSaveSnackbarOpen] = useState(true);
if (!entity && data && requestState === TOKEN_ENTITY_REQUEST_STATES.LOADING) {
const { linkedToken } = data;
if (linkedToken.__typename != `Full${entityType}`) {
const error = `Expecting a ${entityType} but received a ${linkedToken.__typename}`;
console.error(error);
setRequestState(TOKEN_ENTITY_REQUEST_STATES.LOADING_ERROR);
} else {
if (entityType === "Provider") {
setEntity({
...linkedToken,
requests: linkedToken.requests
.filter((x) => !x.satisfied)
.map((x) => x.type),
});
} else {
setEntity(linkedToken);
}
setRequestState(TOKEN_ENTITY_REQUEST_STATES.LOADED);
}
}
if (error && requestState === TOKEN_ENTITY_REQUEST_STATES.LOADING) {
setRequestState(TOKEN_ENTITY_REQUEST_STATES.LOADING_ERROR);
}
const setField = (field) => (value) => {
setEntity((state) => ({
...state,
[field]: value,
}));
};
const save = () => {
setRequestState(TOKEN_ENTITY_REQUEST_STATES.SAVING);
saveEntity({ variables: { token, ...entity } })
.then(({ errors: systemErrors = [], data }) => {
if (systemErrors.length || data.updateProvider.errors.length) {
setRequestState(TOKEN_ENTITY_REQUEST_STATES.SAVING_ERROR);
} else {
setSaveSnackbarOpen(true);
setRequestState(TOKEN_ENTITY_REQUEST_STATES.SAVING_SUCCESS);
}
})
.catch((e) => {
console.error(e);
setRequestState(TOKEN_ENTITY_REQUEST_STATES.SAVING_ERROR);
});
};
const acknowledgeSaveSnackbar = () => setSaveSnackbarOpen(false);
if (saveData && saveData.updateProvider.errors.length) {
return [
requestState,
entity,
saveData.updateProvider.errors.join(". "),
setField,
save,
isSaveSnackbarOpen,
acknowledgeSaveSnackbar,
];
}
return [
requestState,
entity,
error || savingError,
setField,
save,
isSaveSnackbarOpen,
acknowledgeSaveSnackbar,
];
}
Example #24
Source File: PodRedeemForm.jsx From pods-frontend with MIT License | 4 votes |
export function PodRedeemForm({ podAddress, userAddress }) {
const [
amount,
setAmount
] = useState('')
const [
lastRefetchTxId,
setLastRefetchTxId
] = useState(0)
const weiAmount = ethers.utils.parseEther(amount || '0')
let podUser = useQuery(podUserQuery, {
variables: { podAddress, userAddress },
skip: !userAddress || !podAddress
})
let transactions = useQuery(transactionsQuery)
let loading = podUser.loading || transactions.loading
let error = podUser.error || transactions.error
const [redeem, redeemResult] = useMutation(gql`
mutation redeemMutation($podAddress: String!, $amount: Float!) {
sendTransaction(abi: "Pod", address: $podAddress, fn: "redeem", params: [$amount, "0x0"], gasLimit: 900000) @client
}
`, {
variables: {
podAddress,
amount: weiAmount
},
refetchQueries: ['transactionsQuery']
})
let redeemTx
if (!loading && !error && redeemResult.data) {
redeemTx = transactions.data._transactions.find(tx => tx.id === redeemResult.data.sendTransaction.id)
}
if (redeemTx && redeemTx.completed && redeemTx.id > lastRefetchTxId) {
setAmount(0)
podUser.refetch()
setLastRefetchTxId(redeemTx.id)
}
let sufficientBalance = false
if (!loading && !error && podUser.data) {
sufficientBalance = podUser.data.balance.gte(ethers.utils.bigNumberify(weiAmount))
}
return (
<form className="w-full max-w-sm mt-5" onSubmit={(e) => { e.preventDefault(); redeem(); } }>
<div className="md:flex md:items-center mb-3">
<div className="md:w-1/3">
<label className="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" htmlFor="inline-full-name">
Redeem
</label>
</div>
<div className="md:w-2/3">
<input
className="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
id="inline-full-name"
type="text"
placeholder="enter Pod token amount"
value={amount}
onChange={(e) => { e.preventDefault(); setAmount(e.target.value) } }
/>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3"></div>
<div className="md:w-2/3">
<Button
disabled={!sufficientBalance}
onClick={(e) => { e.preventDefault(); redeem(); } }>
Redeem
</Button>
</div>
</div>
</form>
)
}
Example #25
Source File: VolunteerStepper.jsx From feedadoc with MIT License | 4 votes |
export default function VolunteerStepper({ steps, location }) {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [errors, setErrors] = React.useState(null);
const [variables, setVariables] = React.useState({
firstName: "",
lastName: "",
neighborhood: "",
city: "",
state: "",
country: "",
latitude: 0.0,
longitude: 0.0,
address: "",
email: "",
requests: [],
description: "",
availabilities: [],
phone: "",
social: "",
over18: false,
});
const [mapResult, setMapResult] = useState(null);
const [isSuccess, setIsSuccess] = useState(false);
const queryId = queryString.parse(location.search).provider;
let provider;
const providerResult = useQuery(GET_PROVIDER, {
variables: { id: parseInt(queryId) },
});
if (providerResult && providerResult.data && providerResult.data.provider) {
provider = providerResult.data.provider;
}
const [createVolunteer, { loading, data, error }] = useMutation(
CREATE_VOLUNTEER
);
const handleNext = () => {
if (activeStep === steps.length - 1 && variables.over18 === false) {
setErrors(["You must be over 18 years old to volunteer."]);
} else if (activeStep === steps.length - 1) {
createVolunteer({
variables: { ...variables, providerId: parseInt(queryId) },
})
.then(({ errors: systemErrors = [], data }) => {
const {
createVolunteer: { volunteer, errors = [] },
} = data;
const allErrors = [...(errors || []), ...systemErrors].map((e) =>
e && e.message ? e.message : e
);
if (errors.length) {
setErrors(errors);
} else {
setIsSuccess(true);
}
})
.catch((e) => {
setErrors([e.message]);
});
} else {
setActiveStep(activeStep + 1);
}
};
const handleBack = () => {
setActiveStep(activeStep - 1);
};
const setField = (name) => (value) => {
setVariables((vars) => ({ ...vars, [name]: value }));
};
const onChange = (e) => setField(e.target.name)(e.target.value);
const CurrentStep = steps[activeStep] && steps[activeStep].component;
if (isSuccess) {
return <Redirect push to="/volunteer/confirmation" />;
}
if (!provider) return null;
return (
<Paper className={classes.paper}>
<React.Fragment>
<Typography
component="h1"
variant="h6"
align="center"
className={classes.formTitle}
>
Offer Help
</Typography>
<Typography
component="h2"
variant="h5"
align="center"
className={classes.heading}
>
{`Respond to ${provider.firstName}'s request`}
</Typography>
<Typography
component="h3"
variant="h6"
align="center"
className={classes.details}
>
{`The information you provide on this page will be shared with ${provider.firstName}, and they will respond if they still need help. Thank you for volunteering!`}
</Typography>
<Stepper activeStep={activeStep} className={classes.stepper}>
{steps.map(({ label }, index) => (
<Step key={index} onClick={() => setActiveStep(index)}>
<StepLabel className={classes.step}>{label}</StepLabel>
</Step>
))}
</Stepper>
<React.Fragment>
<React.Fragment>
<CurrentStep
onChange={onChange}
setField={setField}
provider={provider}
setMapResult={setMapResult}
mapResult={mapResult}
{...variables}
/>
<div className={classes.buttons}>
{activeStep !== 0 && (
<Button
variant="contained"
onClick={handleBack}
className={classes.backButton}
>
<div className={classes.buttonText}>Back</div>
</Button>
)}
<Button
variant="contained"
onClick={handleNext}
className={classes.forwardButton}
disabled={loading}
>
<div className={classes.buttonText}>
{activeStep === steps.length - 1 ? "Volunteer" : "Next"}
</div>
</Button>
</div>
</React.Fragment>
</React.Fragment>
</React.Fragment>
{errors && (
<Snackbar open={true} onClose={() => setErrors(null)}>
<Paper className={classes.error}>
<ErrorIcon /> {errors.join(" - ")}
</Paper>
</Snackbar>
)}
</Paper>
);
}
Example #26
Source File: PodJoinForm.jsx From pods-frontend with MIT License | 4 votes |
export default function PodJoinForm({ podAddress, userAddress }) {
const [
amount,
setAmount
] = useState('')
const [
lastRefetchTxId,
setLastRefetchTxId
] = useState(0)
const weiAmount = ethers.utils.parseEther(amount || '0')
let pod = useQuery(podQuery, {
variables: { podAddress }
})
let poolAddress = pod.data ? pod.data.poolAddress : null
let podUser = useQuery(podUserQuery, {
variables: { podAddress, userAddress },
skip: !userAddress || !podAddress
})
let pool = useQuery(poolQuery, {
variables: {
podAddress,
poolAddress
},
skip: !poolAddress
})
let tokenAddress = pool.data ? pool.data.tokenAddress : null
// console.log({ podAddress, userAddress, poolAddress, tokenAddress })
let token = useQuery(tokenQuery, {
variables: {
podAddress,
userAddress,
tokenAddress
},
skip: !tokenAddress || !userAddress
})
let transactions = useQuery(transactionsQuery)
let loading = podUser.loading || pool.loading || token.loading || transactions.loading
let error = podUser.error || pool.error || token.error || transactions.error
const [approve, approveResult] = useMutation(gql`
mutation approveMutation($tokenAddress: String!, $podAddress: String!, $amount: Float!) {
sendTransaction(abi: "ERC20", address: $tokenAddress, fn: "approve", params: [$podAddress, $amount]) @client
}
`, {
variables: {
tokenAddress,
podAddress,
amount: weiAmount
},
refetchQueries: ['transactionsQuery']
})
let approveTx
if (!loading && !error && approveResult.data) {
approveTx = transactions.data._transactions.find(tx => tx.id === approveResult.data.sendTransaction.id)
}
const [deposit, depositResult] = useMutation(gql`
mutation depositMutation($podAddress: String!, $amount: Float!) {
sendTransaction(abi: "Pod", address: $podAddress, fn: "deposit", params: [$amount, "0x0"], gasLimit: 1000000) @client
}
`, {
variables: {
podAddress,
amount: weiAmount
},
refetchQueries: ['transactionsQuery']
})
let depositTx
if (!loading && !error && depositResult.data) {
depositTx = transactions.data._transactions.find(tx => tx.id === depositResult.data.sendTransaction.id)
}
if (approveTx && approveTx.completed && approveTx.id > lastRefetchTxId) {
token.refetch()
setLastRefetchTxId(approveTx.id)
}
if (depositTx && depositTx.completed && depositTx.id > lastRefetchTxId) {
setAmount(0)
token.refetch()
podUser.refetch()
pool.refetch()
setLastRefetchTxId(depositTx.id)
}
let needsApproval = true
// let sufficientBalance = false
if (!loading && !error && token.data) {
needsApproval = token.data.allowance.lt(ethers.utils.bigNumberify(weiAmount))
// sufficientBalance = token.data.balance.gte(ethers.utils.bigNumberify(weiAmount))
}
return (
<form className="w-full max-w-sm mt-5" onSubmit={(e) => { e.preventDefault(); needsApproval ? approve() : deposit() } }>
<div className="md:flex md:items-center mb-3">
<div className="md:w-1/3">
<label className="block text-gray-500 font-bold md:text-right mb-1 md:mb-0 pr-4" htmlFor="inline-full-name">
Deposit
</label>
</div>
<div className="md:w-2/3">
<input
className="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-purple-500"
id="inline-full-name"
type="text"
placeholder="enter Dai amount"
value={amount}
onChange={(e) => { e.preventDefault(); setAmount(e.target.value) } }
/>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3"></div>
<div className="md:w-2/3">
<Button
disabled={!needsApproval}
onClick={(e) => { e.preventDefault(); approve(); } }>
Approve
</Button>
<Button
disabled={needsApproval}
onClick={(e) => { e.preventDefault(); deposit(); } }>
Deposit
</Button>
</div>
</div>
</form>
)
}
Example #27
Source File: CartSteps.js From web with MIT License | 4 votes |
CartSteps = () => {
const [country, setCountry] = useState('India');
const [loading, setLoading] = useState(false);
const [activeStep, setActiveStep] = useState(1);
const [userData, setUserData] = useState({});
const [paymentData, setPaymentData] = useState({});
const [orderData, setOrderData] = useState({});
const [discount, setDiscount] = useState(0);
const cartItems = useStoreState(state => state.cart.items);
const location = useStoreState(state => state.user.location);
const emptyCart = useStoreActions(actions => actions.cart.empty);
const [createOrder, { data: createOrderResult }] = useMutation(
createOrderMutation,
);
const [updateOrder] = useMutation(updateOrderMutation);
const [verifyCard, { data: verifyCardResult }] = useMutation(
verifyCardMutation,
);
// console.log('data', data, verifyCardResult, createOrderResult);
useEffect(() => {
if (location && location.country) {
setCountry(location.country);
}
}, [location]);
const handleCreateOrder = async gateway => {
const tokenId = verifyCardResult ? verifyCardResult.verifyCard.id : '';
const orderId = randomstring.generate(6).toUpperCase();
const { email, fullName, ...address } = userData;
const products = cartItems.map(item => {
return { id: item.id, sku: item.sku };
});
const inputData = {
tokenId,
orderId,
customer: { email, fullName, address: { ...address } },
products,
discount,
country: location.country,
currencyCode: location.currencyCode,
};
await createOrder({
variables: {
input: inputData,
gateway,
},
});
};
const finishOrder = () => {
// ReactGA.plugin.execute('ecommerce', 'addTransaction', {
// id: createOrderResult.createOrder.orderId,
// name: 'test checkout', // Product name. Required.
// sku: 'DD23444', // SKU/code.
// category: 'Party Toys', // Category or variation.
// price: '11.99', // Unit price.
// quantity: '1', // Quantity.
// });
// ReactGA.plugin.execute('ecommerce', 'send');
// ReactGA.plugin.execute('ecommerce', 'clear');
setOrderData(createOrderResult.createOrder);
setActiveStep(4);
emptyCart();
};
useEffect(() => {
// make verifyCard mutation to generate token
if (!isEmpty(paymentData)) {
verifyCard({ variables: { input: paymentData } });
}
}, [paymentData]);
useEffect(() => {
if (!verifyCardResult) {
return;
}
handleCreateOrder('stripe');
}, [verifyCardResult]);
useEffect(() => {
// console.log('now show success', createOrderResult);
if (!createOrderResult) {
return;
}
if (country === 'India') {
// use razor pay
const options = {
key: config.razorPayKey, // Enter the Key ID generated from the Dashboard
amount: `${createOrderResult.createOrder.total}00`,
currency: 'INR',
name: config.siteName,
description: config.description,
image: config.logo,
order_id: createOrderResult.createOrder.paymentId, // This is a sample Order ID. Create an Order using Orders API. (https://razorpay.com/docs/payment-gateway/orders/integration/#step-1-create-an-order). Refer the Checkout form table given below
handler() {
// do mutation to update payment ID and payment status to success
updateOrder({
variables: {
input: {
orderId: createOrderResult.createOrder.orderId,
status: 'paid',
},
},
});
finishOrder();
},
prefill: {
name: userData.fullName,
email: userData.email,
contact: userData.telephone,
},
notes: {
address: userData.address,
},
theme: {
color: theme.mainBrandColor,
},
};
const rzp1 = new Razorpay(options);
rzp1.open();
setLoading(false);
} else {
finishOrder();
}
}, [createOrderResult]);
useEffect(() => {
if (!isEmpty(userData) && country === 'India') {
handleCreateOrder('razorpay');
}
}, [userData]);
return (
<section className="section">
<div className="container">
<Heading>Cart</Heading>
<Spring
native
from={{ opacity: 0 }}
to={{
opacity: activeStep !== 1 ? 1 : 0,
// eslint-disable-next-line prettier/prettier
}}
>
{styles => (
<animated.div style={styles}>
<CheckoutProgress activeStep={activeStep} />
</animated.div>
)}
</Spring>
<div className="columns">
<Spring
native
from={{ marginLeft: '25%' }}
// eslint-disable-next-line prettier/prettier
to={{ marginLeft: activeStep === 1 ? '25%' : '0%' }}
>
{stylesProps => (
<animated.div
style={stylesProps}
// eslint-disable-next-line prettier/prettier
className="column section is-half is-hidden-mobile"
>
<CartItems
cartItems={cartItems}
showCheckoutBtn={activeStep === 1}
discount={discount}
setDiscount={setDiscount}
handlePayment={() => {
setActiveStep(2);
}}
/>
</animated.div>
)}
</Spring>
<div
className={`column section ${
activeStep === 2 ? 'is-hidden-mobile' : ''
} is-hidden-tablet`}
>
<CartItems
cartItems={cartItems}
showCheckoutBtn={activeStep === 1}
discount={discount}
setDiscount={setDiscount}
handlePayment={() => {
setActiveStep(2);
}}
/>
</div>
<div className="column section">
{activeStep === 2 && (
<CheckoutForm
enableReinitialize
initialValues={{ country: location.country }}
loading={loading}
handlePayment={data2 => {
setLoading(true);
if (country === 'India') {
// razorpay payment
setUserData(data2);
} else {
// stripe payment
setActiveStep(3);
setUserData(data2);
}
}}
/>
)}
{activeStep === 3 && (
<PaymentForm
handlePayment={data2 => {
setPaymentData(data2);
}}
/>
)}
{activeStep === 4 && <PaymentConfirmed orderData={orderData} />}
</div>
</div>
</div>
</section>
);
}
Example #28
Source File: signup.jsx From dineforward with MIT License | 4 votes |
SignupPage = () => {
const [termsAccepted, setTermsAccepted] = useState(false);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [name, setName] = useState('');
const [errorMessage, setErrorMessage] = useState(null);
const [alertClosed, setAlertClosed] = useState(false);
const router = useRouter();
const [signIn, { loading, client }] = useMutation(gql(CREATE_USER_AND_PASSWORD_AUTH_MUTATION), {
variables: {
user: {
email,
name,
password,
username: email,
isBusiness: true,
},
email,
password,
},
onCompleted: ({ error }) => {
if (error) throw error;
// Ensure there's no old unauthenticated data hanging around
client.resetStore();
// Don't use the Next.js client-side router here. We must load the
// next page from the server to trigger the server-side user setup
// in withIdentity.
if (typeof window !== 'undefined') window.location.href = nextPage;
else router.push(nextPage);
},
onError: e => {
let msg = e.message || 'Unknown error';
if (/duplicate key error/.test(msg)) {
msg = 'That email address has already been signed up';
}
setErrorMessage(msg);
console.error('User signup error:', e);
},
});
const onSubmit = e => {
e.preventDefault();
closeAlert();
if (!name) {
setErrorMessage(`Please provide a Name`);
return;
}
if (!email) {
setErrorMessage(`Please provide an email address`);
return;
}
if (!password) {
setErrorMessage(`Please provide a password`);
return;
}
if (!loading) signIn();
};
const closeAlert = () => {
setAlertClosed(true);
setErrorMessage(null);
};
const displayError = (!alertClosed && router.query.error) || errorMessage;
const toggleTerms = () => setTermsAccepted(!termsAccepted);
React.useEffect(() => {
window.scrollTo(0, 0);
document.body.scrollTop = 0;
});
const classes = useStyles();
const errorPage = router.pathname + '?error=${message}'; // Template string interpreted later;
const authLink = authType =>
`/auth/${authType}?operation=create&isbusiness=true&onsuccess=${nextPage}&onfailure=${errorPage}`;
return (
<div>
<div
className={classes.pageHeader}
style={
{
// backgroundImage: 'url(' + image + ')',
// backgroundSize: 'cover',
// backgroundPosition: 'top center',
}
}
>
<div className={classes.container}>
<Grid container component="main" className={classes.root}>
<CssBaseline />
<Grid item xs={false} sm={4} md={7} className={classes.image} />
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<div className={classes.paper}>
{displayError ? (
<Alert severity="error" onClose={closeAlert}>
{displayError}
</Alert>
) : null}
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign Up
</Typography>
<FormControlLabel
classes={{
label: classes.label,
}}
control={
<Checkbox
tabIndex={-1}
onClick={toggleTerms}
checkedIcon={<Check className={classes.checkedIcon} />}
icon={<CheckBoxOutlineBlankIcon className={classes.uncheckedIcon} />}
classes={{
checked: classes.checked,
root: classes.checkRoot,
}}
checked={termsAccepted}
/>
}
label={
<span>
I agree to the <a href="/terms">terms and conditions</a>.
</span>
}
/>
<div className={classes.textCenter}>
<Button color="google" href={authLink('google')} disabled={!termsAccepted}>
<i className="fab fa-google-plus-square" /> Sign in with Google
</Button>
{` `}
<Button color="facebook" href={authLink('facebook')} disabled={!termsAccepted}>
<i className="fab fa-facebook-square" /> Login with Facebook
</Button>
{` `}
<h4 className={classes.socialTitle}>or with email</h4>
</div>
<form className={classes.form} onSubmit={onSubmit}>
<TextField
className={classes.customFormControlClasses}
fullWidth
placeholder="Name..."
value={name}
onChange={e => setName(e.target.value)}
/>
<TextField
className={classes.customFormControlClasses}
fullWidth
autoComplete="email"
type="email"
placeholder="Email..."
value={email}
onChange={e => setEmail(e.target.value)}
/>
<TextField
className={classes.customFormControlClasses}
fullWidth
autoComplete="new-password"
type="password"
placeholder="Password..."
value={password}
onChange={e => setPassword(e.target.value)}
/>
<div className={classes.textCenter}>
<Button
type="submit"
disabled={loading || !termsAccepted}
color="primary"
>
Get started
</Button>
</div>
</form>
</div>
</Grid>
</Grid>
</div>
</div>
</div>
);
}
Example #29
Source File: MapResults.js From willow-grandstack with Apache License 2.0 | 4 votes |
export default function MapResults(props) {
console.log(props.properties)
const theme = useTheme()
const [onStarHandler, { data, loading, error }] = useMutation(gql`
mutation starPropertyMutation($id: ID!) {
starProperty(id: $id) {
id
address
}
}
`)
const style = {
padding: '4px',
color: '#fff',
cursor: 'pointer',
background: '#1978c8',
borderRadius: '50%',
}
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
paper: {
padding: theme.spacing(2),
display: 'flex',
overflow: 'auto',
flexDirection: 'column',
},
fixedHeight: {
height: 540,
},
}))
const classes = useStyles(theme)
const fixedHeightPaper = clsx(classes.paper, classes.fixedHeight)
const [viewport, setViewport] = useState({
latitude: 45.667397,
longitude: -111.054718,
zoom: 13,
})
const [currentProperty, setCurrentProperty] = useState(props.properties[0])
return (
<React.Fragment>
<Grid container spacing={4}>
<Grid item xs={12} md={2} lg={2}>
<Paper className={fixedHeightPaper}>
<StarredProperties />
</Paper>
</Grid>
<Grid item xs={12} md={7} lg={6}>
<Paper className={fixedHeightPaper}>
<MapGL
style={{ width: '100%', height: '100%' }}
mapStyle="mapbox://styles/mapbox/light-v9"
accessToken={process.env.REACT_APP_MAPBOX_TOKEN}
latitude={viewport.latitude}
longitude={viewport.longitude}
zoom={viewport.zoom}
onViewportChange={setViewport}
>
{props.properties.map((p, i) => {
return (
<Marker
key={i}
longitude={p.location.longitude}
latitude={p.location.latitude}
>
<div
onClick={() => setCurrentProperty(p)}
style={style}
></div>
</Marker>
)
})}
</MapGL>
</Paper>
</Grid>
<Grid item xs={12} md={3} lg={4}>
<Paper className={fixedHeightPaper}>
<p>{currentProperty.address}</p>
<Button
onClick={() =>
onStarHandler({ variables: { id: currentProperty.id } })
}
>
Star Property
</Button>
<ul>
<li>Square feet: {currentProperty.sqft}</li>
<li>Bedrooms: {currentProperty.bedrooms}</li>
<li>Full baths: {currentProperty.full_baths}</li>
<li>Half baths: {currentProperty.half_baths}</li>
</ul>
<GridList cellHeight={160} cols={2}>
{currentProperty.photos.map((v, i) => (
<GridListTile key={i} cols={1}>
<img src={v.url}></img>
</GridListTile>
))}
</GridList>
</Paper>
</Grid>
</Grid>
</React.Fragment>
)
}