@apollo/react-hooks#useLazyQuery JavaScript Examples
The following examples show how to use
@apollo/react-hooks#useLazyQuery.
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: View.jsx From saasgear with MIT License | 6 votes |
ViewDocument = () => {
const match = useRouteMatch();
const documentId = parseInt(match.params.id, 10);
const [fetchDocumentDetail, { data: documentData, loading }] = useLazyQuery(
getDocumentDetailQuery,
);
useEffect(() => {
if (documentId) {
fetchDocumentDetail({ variables: { id: documentId } });
}
}, [documentId]);
function createMarkup(html) {
return {
__html: DOMPurify.sanitize(html),
};
}
return (
<ContentDocument>
{loading && <div>Loading...</div>}
{!loading && documentData?.getDocumentDetail && (
<>
<TitlePage>{documentData.getDocumentDetail.name}</TitlePage>
<ContentPage>
<div
dangerouslySetInnerHTML={createMarkup(
documentData.getDocumentDetail.body,
)}
></div>
</ContentPage>
</>
)}
</ContentDocument>
);
}
Example #2
Source File: SubCategoryPage.jsx From trashpanda-fe with MIT License | 5 votes |
SubCategoryPage = () => {
const { subCategoryId } = useParams();
const [currentData, setCurrentData] = useState(null);
const history = useHistory();
const [materialList, setMaterialList] = useState([]);
const [getMaterials, materialInfo] = useLazyQuery(GET_MATERIALS);
useEffect(() => {
const foundData = data.find(dataObj => dataObj.id == subCategoryId);
setCurrentData(foundData);
}, [subCategoryId]);
useEffect(() => {
if (currentData)
getMaterials({
variables: {
idList: currentData.materialIds
}
});
}, [currentData]);
useEffect(() => {
if (materialInfo.data && materialInfo.data.getMaterialByIDS) {
setMaterialList(materialInfo.data.getMaterialByIDS);
}
}, [materialInfo.data]);
if (materialInfo.loading) return <Spinner />;
return (
<Root>
<Title>{currentData && currentData.title}</Title>
<Blurb>
You can find which type of plastic your item is by looking for the
numbered stamp, usually located near the bottom.
</Blurb>
<Container>
{materialList &&
materialList.map((material, key) => (
<GridCard
svg={getPlasticTypeImage(material.description)}
name={getPlasticName(material.description)}
key={key}
onClick={() => history.push(`/material/${material.material_id}`)}
/>
))}
</Container>
</Root>
);
}
Example #3
Source File: index.js From monorepo-starter with MIT License | 5 votes |
function HomePage() {
const { data: authorList, initialLoading, initialError } = useQuery(
getAuthors
);
const [getAuthor, { loading, error, data }] = useLazyQuery(getAuthorDetails);
if (!authorList) {
return null;
}
return (
<div
style={{
textAlign: "center"
}}
>
<Preamble />
<h2>
As a treat, we've got some cool author recs Click on an author to see
some of their books:
</h2>
<div>
{authorList.authors.map(({ name }) => (
<Button
key={name}
isSelected={data && data.author.name === name}
onClick={() => {
getAuthor({ variables: { name } });
}}
>
{name}
</Button>
))}
</div>
<div style={{ marginTop: "24px" }}>
{data ? (
<div>
<ul>
{data.author.books.map(({ title }) => (
<li style={{ listStyle: "none" }} key={title}>
{title}
</li>
))}
</ul>
</div>
) : null}
</div>
</div>
);
}
Example #4
Source File: PokemonDetail.js From react-sample-projects with MIT License | 5 votes |
PokemonDetail = () => {
const dispatch = useDispatch();
const pokemonDetail = useSelector((state) => state.pokemonDetail) || {};
const britishNumberFormatter = new Intl.NumberFormat('en-GB');
const params = useParams();
const navigate = useNavigate();
const { state } = useLocation();
const [getPokemonDetails, { loading, error, data }] = useLazyQuery(
GET_POKEMON_DETAILS,
{
variables: { id: params.id },
},
);
useEffect(() => {
if (state && state?.pokemon) {
dispatch({ type: 'SET_POKEMON_DETAILS', payload: state.pokemon });
} else if (params.id) {
getPokemonDetails();
}
return () => {};
}, [dispatch, getPokemonDetails, state, params.id]);
const goBack = () => {
navigate(-1);
};
if (loading) return <p>Loading ...</p>;
if (error) return <pre>{error}</pre>;
if (data) {
dispatch({ type: 'SET_POKEMON_DETAILS', payload: data.pokemon });
}
return (
<div className="pokemondetail">
<button onClick={goBack}> Back</button>
<div className="pokemon">
<div className="pokemon__name">
<h1>{pokemonDetail.name}</h1>
</div>
<h4>Classification: {pokemonDetail.classification}</h4>
<div className="pokemon__meta">
<span>
maxHP: {britishNumberFormatter.format(pokemonDetail.maxHP)}
</span>
<span>
maxCP: {britishNumberFormatter.format(pokemonDetail.maxCP)}
</span>
</div>
<br />
<div className="pokemon__image">
<img src={pokemonDetail.image} alt={pokemonDetail.name} />
</div>
<h1>Resistant</h1>
<div className="pokemon__attacks">
{pokemonDetail?.resistant?.map((resistant, index) => (
<span key={index}>{resistant} </span>
))}
</div>
<h1>Weaknesses</h1>
<div className="pokemon__attacks">
{pokemonDetail?.weaknesses?.join(', ')}
</div>
<h1>Attacks</h1>
<div className="pokemon__attacks">
<p>{pokemonDetail?.attacks?.fast.map((f) => f.name).join(', ')}</p>
<p>{pokemonDetail?.attacks?.special.map((s) => s.name).join(', ')}</p>
</div>
</div>
</div>
);
}
Example #5
Source File: ProfilePage.js From lifebank with MIT License | 4 votes |
ProfilePage = () => {
const { t } = useTranslation('translations')
const classes = useStyles()
const history = useHistory()
const [, { logout }] = useUser()
const [openAlert, setOpenAlert] = useState(false)
const [messegaAlert, setMessegaAlert] = useState("")
const [severity, setSeverity] = useState("success")
const [lastConsentChange, setLastConsentChange] = useState()
const [currentUser] = useUser()
const handleOpenAlert = () => {
setOpenAlert(!openAlert)
}
const [
loadProfile,
{ client, error: errorProfile, loading, data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const [
revokeConsent,
{
error: errorRevokeConsent,
loading: revokeConsentLoading,
data: { revoke_consent: revokeConsentResult } = {}
}
] = useMutation(REVOKE_CONSENT_MUTATION)
const [
grantConsent,
{
error: errorGrantConsent,
loading: grantConsentLoading,
data: { grant_consent: grantConsentResult } = {}
}
] = useMutation(GRANT_CONSENT_MUTATION)
const handleConsentChange = () => {
setLastConsentChange(profile?.consent ? 'revoke' : 'grant')
profile?.consent ? revokeConsent() : grantConsent()
}
useEffect(() => {
if (!currentUser) {
client && client.resetStore()
history.replace('/')
return
}
loadProfile()
}, [currentUser, history, client, loadProfile])
useEffect(() => {
if (
!lastConsentChange ||
(lastConsentChange === 'grant' && !grantConsentResult) ||
(lastConsentChange === 'revoke' && !revokeConsentResult)
) {
return
}
if (lastConsentChange === 'grant') {
setSeverity("success")
setMessegaAlert(t('signup.consentGranted'))
handleOpenAlert()
} else {
setSeverity("success")
setMessegaAlert(t('signup.consentRevoked'))
handleOpenAlert()
}
loadProfile()
}, [
handleOpenAlert,
t,
loadProfile,
grantConsentResult,
revokeConsentResult,
lastConsentChange,
classes
])
useEffect(() => {
if (profile && !profile.consent) {
setSeverity("error")
setMessegaAlert(t('signup.noConsentNoEdit'))
handleOpenAlert()
}
}, [t, setSeverity, setMessegaAlert, profile])
useEffect(() => {
if (errorProfile) {
if (errorProfile.message === 'GraphQL error: Could not verify JWT: JWTExpired') {
logout()
history.push('/')
} else history.push('/internal-error')
}
}, [logout, history, errorProfile])
useEffect(() => {
if (errorRevokeConsent) {
if (errorRevokeConsent.message === 'GraphQL error: Could not verify JWT: JWTExpired') {
logout()
history.push('/')
} else {
setSeverity("error")
setMessegaAlert(t('signup.consentError'))
handleOpenAlert()
}
}
}, [t, logout, history, errorRevokeConsent])
useEffect(() => {
if (errorGrantConsent) {
if (errorGrantConsent.message === 'GraphQL error: Could not verify JWT: JWTExpired') {
logout()
history.push('/')
} else {
setSeverity("error")
setMessegaAlert(t('signup.consentError'))
handleOpenAlert()
}
}
}, [t, logout, history, errorGrantConsent])
return (
<Box className={classes.contentBody}>
<Snackbar open={openAlert} autoHideDuration={6000} onClose={handleOpenAlert}>
<Alert onClose={handleOpenAlert} severity={severity}>
{messegaAlert}
</Alert>
</Snackbar>
{loading && <CircularProgress />}
{!loading && currentUser && profile?.role === 'donor' && (
<Suspense fallback={<CircularProgress />}>
<ProfilePageDonor
profile={profile}
onConsentChange={handleConsentChange}
loading={grantConsentLoading || revokeConsentLoading}
/>
</Suspense>
)}
{!loading && currentUser && profile?.role === 'sponsor' && (
<Suspense fallback={<CircularProgress />}>
<ProfilePageSponsor profile={profile} />
</Suspense>
)}
{!loading && currentUser && profile?.role === 'lifebank' && (
<Suspense fallback={<CircularProgress />}>
<ProfilePageLifebank profile={profile} />
</Suspense>
)}
{!currentUser &&
<Suspense fallback={<CircularProgress />}>
<ProfilePageGuest />
</Suspense>}
</Box>
)
}
Example #6
Source File: CameraPage.jsx From trashpanda-fe with MIT License | 4 votes |
CameraPage = ({
theme,
setShutterPress,
shutterPress,
setAppCluster,
setSearchFocus
}) => {
const [image, setImage] = useState();
const videoRef = useRef(null);
const [cameraInstance, setCameraInstance] = useState();
const [loading, setLoading] = useState(true);
const [getCluster, ClusterData] = useLazyQuery(GET_CLUSTER);
const handleShutterButton = () => {
setShutterPress(true);
};
useEffect(() => {
if (!ClusterData.loading) {
setLoading(false);
}
if (!ClusterData.loading && ClusterData.data) {
setAppCluster(ClusterData.data.getCluster);
}
}, [ClusterData]);
useEffect(() => {
if (shutterPress) {
const config = {
sizeFactor: 1
};
if (cameraInstance) {
const dataUri = cameraInstance.getDataUri(config);
setImage({ dataUri });
cameraInstance.stopCamera();
getCluster({
variables: {
imageData: dataUri
}
});
setLoading(true);
}
} else {
setImage(null);
setLoading(true);
startCam(cameraInstance, setLoading);
}
}, [shutterPress]);
useEffect(() => {
// create video stream
if (videoRef) {
const cameraPhoto = new CameraPhoto(videoRef.current);
setCameraInstance(cameraPhoto);
}
}, [videoRef]);
useEffect(() => {
startCam(cameraInstance, setLoading);
return function cleanup() {
if (cameraInstance && cameraInstance.stream) {
console.log("running cleanup");
setImage(null);
setShutterPress(false);
cameraInstance
.stopCamera()
.then(() => {
console.log("stopped camera");
})
.catch(err => console.log("camera not running"));
}
};
}, [cameraInstance]);
return (
<Root>
{loading && <Spinner />}
<StyledVideo
hidden={shutterPress || !videoRef}
ref={videoRef}
autoPlay={true}
/>
{image && <img src={image.dataUri} alt="camera image" />}
{!ClusterData.loading && (ClusterData.data || ClusterData.error) && (
<ClusterResult
shutterPress={shutterPress}
setShutterPress={setShutterPress}
ClusterData={ClusterData}
setSearchFocus={setSearchFocus}
/>
)}
{!shutterPress && (
<FullFrame>
<StyledShutterButton onClick={handleShutterButton}>
<ShutterButton theme={theme} />
</StyledShutterButton>
</FullFrame>
)}
</Root>
);
}
Example #7
Source File: OffersManagement.js From lifebank with MIT License | 4 votes |
OffersManagement = () => {
const { t } = useTranslation('translations')
const classes = useStyles()
const [offers, setOffers] = useState(undefined)
const [profileIDLoaded, setProfileIDLoaded] = useState(false)
const [offersLoaded, setOffersLoaded] = useState(false)
const timezone = moment.tz.guess()
const [open, setOpen] = useState(false)
const [openDeleteDialog, setOpenDeleteDialog] = useState(false)
const [offerIDToDelete, setOfferIDToDelete] = useState()
const [offerToEdit, setOfferToEdit] = useState()
const [openGenericFormAddVariant, setOpenGenericFormAddVariant] = useState(
false
)
const [openGenericFormEditVariant, setOpenGenericFormEditVariant] = useState(
false
)
const [clickedOffer, setClickedOffer] = useState()
const [openSnackbar, setOpenSnackbar] = useState({
show: false,
message: '',
severity: 'success'
})
const { refetch: getSponsorOffers } = useQuery(GET_SPONSOR_OFFERS_QUERY, {
variables: {
sponsor_id: 17
},
skip: true
})
const checkAvailableFields = () => {
let pendingFieldsObject = {}
if (!profile.address)
pendingFieldsObject = { ...pendingFieldsObject, address: false }
if (!profile.about)
pendingFieldsObject = { ...pendingFieldsObject, about: false }
if (!profile.logo_url)
pendingFieldsObject = { ...pendingFieldsObject, logo_url: false }
if (!profile.name)
pendingFieldsObject = { ...pendingFieldsObject, name: false }
if (!profile.telephones)
pendingFieldsObject = { ...pendingFieldsObject, telephones: false }
if (!profile.photos)
pendingFieldsObject = { ...pendingFieldsObject, photos: false }
if (!profile.social_media_links)
pendingFieldsObject = {
...pendingFieldsObject,
social_media_links: false
}
if (!profile.website)
pendingFieldsObject = { ...pendingFieldsObject, website: false }
if (!profile.schedule)
pendingFieldsObject = { ...pendingFieldsObject, schedule: false }
if (!profile.location)
pendingFieldsObject = { ...pendingFieldsObject, location: false }
if (Object.keys(pendingFieldsObject).length > 0) {
setOpenGenericFormAddVariant(false)
setOpenSnackbar({
show: true,
message: t("offersManagement.info"),
severity: 'warning'
})
} else {
setOpenGenericFormAddVariant(true)
}
}
const [
loadProfileID,
{ data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_ID_QUERY, { fetchPolicy: 'network-only' })
const [
updateOffer,
{ data: { update_offer: updateOfferResult } = {} }
] = useMutation(UPDATE_OFFER_AVAILABILITY_MUTATION)
const [deleteOffer] = useMutation(DELETE_OFFER_MUTATION)
const deleteOfferRequest = async () => {
setOpenDeleteDialog(false)
await deleteOffer({
variables: {
id: offerIDToDelete
}
})
setOffers(offers.filter((offer) => offer.id !== offerIDToDelete))
}
const handleActionClick = async (action, active, offer_id) => {
switch (action) {
case 'delete':
setOfferIDToDelete(offer_id)
setOpenDeleteDialog(true)
break
case 'deactivate':
await updateOffer({
variables: {
id: offer_id,
active: !active
}
})
break
case 'activate':
await updateOffer({
variables: {
id: offer_id,
active: !active
}
})
break
case 'edit':
setOpenGenericFormEditVariant(true)
setOfferToEdit(offers.find((o) => o.id === offer_id))
break
default:
break
}
}
const [anchorEl, setAnchorEl] = useState(null)
const handleClick = (event) => {
setAnchorEl(event.currentTarget)
};
const handleCloseMenu = () => {
setAnchorEl(null)
};
const Actions = (active, offer_id) => (
<div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
<MoreVertIcon />
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
value=""
open={Boolean(anchorEl)}
onClose={handleCloseMenu}
>
<MenuItem onClick={(e) => handleActionClick("edit", active, offer_id)}>{t('common.edit')}</MenuItem>
<MenuItem onClick={(e) => handleActionClick("delete", active, offer_id)}>{t('common.delete')}</MenuItem>
<MenuItem onClick={(e) => handleActionClick(active ? 'deactivate' : 'activate', active, offer_id)}>
{active
? t('offersManagement.deactivate')
: t('offersManagement.activate')}
</MenuItem>
</Menu>
</div>
)
const handleOpenClick = (offer) => {
setOpen(true)
setClickedOffer(offer)
}
const handleCallback = () => {
setOpenSnackbar({
show: true,
message: t('offersManagement.offerCreation'),
severity: 'success'
})
}
const handleClose = (_event, reason) => {
if (reason === 'clickaway') return
setOpenSnackbar({ ...openSnackbar, show: false })
}
const getGenericOfferComponent = (editing, data) => {
return (
<GenericOfferFormComponent
open={editing ? openGenericFormEditVariant : openGenericFormAddVariant}
setOpen={
editing ? setOpenGenericFormEditVariant : setOpenGenericFormAddVariant
}
setOffers={setOffers}
sponsor_id={profile.id}
isEditing={editing}
data={data}
offerNotification={handleCallback}
/>
)
}
useEffect(() => {
const getOffers = async () => {
const { data } = await getSponsorOffers({
sponsor_id: profile.id
})
data && setOffers(data.offer)
setOffersLoaded(true)
}
if (profileIDLoaded) getOffers()
})
useEffect(() => {
loadProfileID()
}, [loadProfileID])
useEffect(() => {
if (profile) setProfileIDLoaded(true)
}, [profile])
useEffect(() => {
if (updateOfferResult) {
const newArr = [...offers]
const indexToUpdate = offers.findIndex(
(o) => o.id === updateOfferResult.returning[0].id
)
newArr[indexToUpdate].active = !newArr[indexToUpdate].active
setOffers(newArr)
setOpenSnackbar({
show: true,
message: t('offersManagement.offerAvailabilityUpdatedMessage'),
severity: 'success'
})
}
}, [t, offers, updateOfferResult])
return (
<Box className={classes.root}>
{!offersLoaded &&
<Box className={classes.content}>
<CircularProgress />
<Typography className={classes.title} >{t('common.loading')}...</Typography>
</Box>
}
{offersLoaded &&
<>
{offers && offers.length > 0 &&
<Box className={classes.tableContent} >
<Typography className={classes.title} >{t('offersManagement.offersManagement')}</Typography>
<MUIDataTable
title={t('offersManagement.tableTitle')}
data={offers.map((offer, key) => [
<Button
key={key}
className={classes.offerName}
onClick={() => handleOpenClick(offer)}
aria-label="delete"
>
{offer.offer_name}
</Button>,
offer.active
? t('offersManagement.active')
: t('offersManagement.inactive'),
offer.start_date
? m(offer.start_date).tz(timezone).format('DD-MM-YYYY')
: <Typography className={classes.script}>{t('offersManagement.noProvidedDate')}</Typography>,
offer.end_date
? m(offer.end_date).tz(timezone).format('DD-MM-YYYY')
: <Typography className={classes.script}>{t('offersManagement.noProvidedDate')}</Typography>,
Actions(offer.active, offer.id),
])}
columns={[
{
name: t('offersManagement.offerName'),
options: {
filter: true,
}
},
{
name: t('offersManagement.status'),
options: {
filter: true,
}
},
{
name: t('offersManagement.startDate'),
options: {
filter: true,
}
},
{
name: t('offersManagement.endDate'),
options: {
filter: true,
}
},
{
name: t('offersManagement.actions'),
options: {
filter: false,
}
}
]}
options={{
print: false,
selectableRowsHideCheckboxes: true,
selectableRowsHeader: false,
download: false,
}}
/>
</Box>
}
{offers.length === 0 &&
<Box className={classes.content}>
<Typography className={classes.title}>
{t('offersManagement.youHaveNoAddedOffers')}
</Typography>
<Button
variant="contained"
color="secondary"
className={classes.btnAction}
onClick={checkAvailableFields}
>
{t('offersManagement.addOffer')}
</Button>
</Box>
}
</>
}
{open &&
<OfferDetails offer={clickedOffer} open={open} setOpen={setOpen} />
}
<Fab
size="medium"
className={classes.fab}
color="secondary"
aria-label="add"
onClick={checkAvailableFields}
>
<AddIcon />
</Fab>
{openGenericFormAddVariant && profileIDLoaded &&
getGenericOfferComponent(false, undefined)
}
{offerToEdit &&
getGenericOfferComponent(true, offerToEdit)
}
<Dialog open={openDeleteDialog} aria-labelledby="delete-dialog-title">
<DialogTitle id="delete-dialog-title">
{t('offersManagement.deleteOfferConfirmation')}
</DialogTitle>
<DialogActions>
<Button
autoFocus
onClick={() => setOpenDeleteDialog(false)}
color="primary"
>
{t('common.cancel')}
</Button>
<Button onClick={deleteOfferRequest} color="primary" autoFocus>
{t('offersManagement.yesDeleteIt')}
</Button>
</DialogActions>
</Dialog>
<Snackbar
open={openSnackbar.show}
autoHideDuration={2000}
onClose={handleClose}
>
<Alert severity={openSnackbar.severity}>{openSnackbar.message}</Alert>
</Snackbar>
</Box>
)
}
Example #8
Source File: HistoryDashboard.js From lifebank with MIT License | 4 votes |
HistoryDashboard = (user) => {
const { t } = useTranslation('translations')
const classes = useStyles()
const [bodyReceive, setBodyReceive] = useState()
const [bodySent, setBodySent] = useState()
const [currentUser] = useUser()
const [optionSR, setOption] = useState('sent')
const options = [
{ value: 'sent', label: t('historyDashboard.tableTitleSent') },
{ value: 'received', label: t('historyDashboard.tableTitleReceived') }
]
const [
getReportQuery,
{ data: { get_report: getReportResult } = {} }
] = useLazyQuery(GET_REPORT_QUERY, { fetchPolicy: 'network-only' })
const formatDataToReport = () => {
const sent = getReportResult.notifications.sent
const received = getReportResult.notifications.received
setBodyReceive(received)
setBodySent(sent)
}
const formatDataToDonorReport = () => {
const sent = getReportResult.notifications.sent
const received = getReportResult.notifications.received
setBodyReceive(received)
setBodySent(sent)
}
const handleChange = (event) => {
setOption(event.target.value);
}
useEffect(() => {
if (!getReportResult) {
getReportQuery()
} else {
if (currentUser && (currentUser.role === 'lifebank' || currentUser.role === 'sponsor')) formatDataToReport()
else if (currentUser && currentUser.role === 'donor') formatDataToDonorReport()
else return
}
}, [getReportQuery, currentUser, getReportResult])
return (
<>
<Box className={classes.root} >
<Typography className={classes.title} >{t('historyDashboard.title')}</Typography>
<Box className={classes.boxSelect}>
<FormControl variant="filled" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">{t('historyDashboard.dashboard')}</InputLabel>
<Select
labelId="demo-simple-select-filled-label"
id="demo-simple-select-filled"
value={optionSR}
onChange={handleChange}
label="optionSR"
>
{options.map((option) => {
return (
<MenuItem
key={option.value}
value={option.value}
>
{option.label}
</MenuItem>
)
})}
</Select>
</FormControl>
</Box>
<Box className={classes.root}>
{optionSR === 'sent' && (
<Box>
{bodySent && bodySent.length > 0 &&
<Box className={classes.tableContent} >
<MUIDataTable
title={t('historyDashboard.tableTitleSent')}
data={bodySent.map((notification) => [
notification.send_to,
notification.created_at_date,
notification.created_at_time,
notification.tokens
])}
columns={[
{
name: t('historyDashboard.donor'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.date'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.time'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.tokens'),
options: {
filter: true,
}
}
]}
options={{
print: false,
selectableRowsHideCheckboxes: true,
selectableRowsHeader: false,
download: false,
}}
/>
</Box>
}
</Box>)}
{optionSR === 'received' && (
<Box>
{bodyReceive && bodyReceive.length > 0 &&
<Box className={classes.tableContent} >
<MUIDataTable
title={t('historyDashboard.tableTitleSent')}
data={bodyReceive.map((notification) => [
notification.send_to,
notification.created_at_date,
notification.created_at_time,
notification.tokens
])}
columns={[
{
name: t('historyDashboard.donor'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.date'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.time'),
options: {
filter: true,
}
},
{
name: t('historyDashboard.tokens'),
options: {
filter: true,
}
}
]}
options={{
print: false,
selectableRowsHideCheckboxes: true,
selectableRowsHeader: false,
download: false,
}}
/>
</Box>
}
</Box>)}
</Box>
</Box>
</>
)
}
Example #9
Source File: EditProfile.js From lifebank with MIT License | 4 votes |
EditProfilePage = () => {
const { t } = useTranslation('translations')
const classes = useStyles()
const history = useHistory()
const [, { logout }] = useUser()
const [currentUser] = useUser()
const [openSnackbar, setOpenSnackbar] = useState(false)
const theme = useTheme()
const isDesktop = useMediaQuery(theme.breakpoints.up('md'), {
defaultMatches: false
})
const [
loadProfile,
{ error: errorProfile, loading, data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const [
revokeConsent,
{
error: errorRevokeConsent,
loading: revokeConsentLoading,
data: { revoke_consent: revokeConsentResult } = {}
}
] = useMutation(REVOKE_CONSENT_MUTATION)
const [
grantConsent,
{
error: errorGrantConsent,
loading: grantConsentLoading,
data: { grant_consent: grantConsentResult } = {}
}
] = useMutation(GRANT_CONSENT_MUTATION)
const [
editProfile,
{ error: errorEditResults, loading: editLoading, data: { edit_profile: editProfileResult } = {} }
] = useMutation(EDIT_PROFILE_MUTATION)
const [setUsername] = useMutation(SET_USERNAME)
const handleConsentChange = () => {
profile?.consent ? revokeConsent() : grantConsent()
}
const handleUpdateUser = (userEdited, userNameEdited, account) => {
editProfile({
variables: {
profile: userEdited
}
})
if (account && userNameEdited) {
setUsername({
variables: {
account: account,
username: userNameEdited
}
})
}
}
const handleCloseSnackBar = () => {
setOpenSnackbar({ ...openSnackbar, show: false })
}
useEffect(() => {
if (!currentUser) {
return
}
loadProfile()
}, [currentUser, loadProfile])
useEffect(() => {
if (grantConsentResult || revokeConsentResult) {
loadProfile()
}
}, [grantConsentResult, revokeConsentResult, loadProfile])
useEffect(() => {
if (!editProfileResult) return
const { success } = editProfileResult
if (success) {
history.push({
pathname: '/profile',
state: true
})
} else if (!success) {
setOpenSnackbar({
show: true,
message: t('editProfile.duringSaveProfileData'),
severity: 'error'
})
}
}, [t, history, editProfileResult])
useEffect(() => {
if (errorProfile) {
if (errorProfile.message === 'GraphQL error: Could not verify JWT: JWTExpired') {
logout()
history.push('/')
} else history.push('/internal-error')
}
}, [logout, history, errorProfile])
useEffect(() => {
if (errorRevokeConsent || errorGrantConsent || errorEditResults) {
setOpenSnackbar({
show: true,
message: t('editProfile.duringSaveProfileData'),
severity: 'error'
})
}
}, [t, errorRevokeConsent, errorGrantConsent, errorEditResults])
return (
<>
{isDesktop && (
<Box className={classes.wrapper}>
{loading && <CircularProgress />}
{!loading && currentUser && profile?.role === 'donor' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileDonor
profile={profile}
onConsentChange={handleConsentChange}
loading={grantConsentLoading || revokeConsentLoading || editLoading}
onSubmit={handleUpdateUser}
/>
</Suspense>
)}
{!loading && currentUser && profile?.role === 'sponsor' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileSponsor
profile={profile}
onSubmit={handleUpdateUser}
loading={editLoading}
/>
</Suspense>
)}
{!loading && currentUser && profile?.role === 'lifebank' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileBank
profile={profile}
userName={profile.username}
onSubmit={handleUpdateUser}
loading={editLoading}
/>
</Suspense>
)}
</Box >
)}
{!isDesktop && (
<Box className={classes.wrapperMobile}>
{loading && <CircularProgress />}
{!loading && currentUser && profile?.role === 'lifebank' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileBankMobile
profile={profile}
userName={profile.username}
onSubmit={handleUpdateUser}
loading={editLoading}
/>
</Suspense>
)}
{!loading && currentUser && profile?.role === 'sponsor' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileSponsorMobile
profile={profile}
onSubmit={handleUpdateUser}
loading={editLoading}
/>
</Suspense>
)}
{!loading && currentUser && profile?.role === 'donor' && (
<Suspense fallback={<CircularProgress />}>
<EditProfileDonor
profile={profile}
onConsentChange={handleConsentChange}
loading={grantConsentLoading || revokeConsentLoading || editLoading}
onSubmit={handleUpdateUser}
/>
</Suspense>
)}
</Box>
)}
<Snackbar open={openSnackbar.show} autoHideDuration={4000} onClose={handleCloseSnackBar}>
<Alert
severity={openSnackbar.severity}
action={
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={handleCloseSnackBar}
>
<CloseIcon fontSize="inherit" />
</IconButton>
}
>
<AlertTitle>{t('editProfile.error')}</AlertTitle>
{openSnackbar.message}
</Alert>
</Snackbar>
</>
)
}
Example #10
Source File: TransactionReport.js From lifebank with MIT License | 4 votes |
TransactionReport = ({ dateFrom, dateTo, saveReport, onReportSaved }) => {
const { t } = useTranslation('translations')
const [currentUser] = useUser()
const [headReceive, setHeadReceived] = useState()
const [bodyReceive, setBodyReceive] = useState()
const [bodySent, setBodySent] = useState()
const [
loadProfile,
{ data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const headSent = [
[
t('report.donor'),
t('report.date'),
t('report.time'),
t('report.tokens')
]
]
const [
getReportQuery,
{ data: { get_report: getReportResult } = {} }
] = useLazyQuery(GET_REPORT_QUERY, { fetchPolicy: 'network-only' })
useEffect(() => {
if (!profile) loadProfile()
}, [loadProfile, profile])
useEffect(() => {
if (!getReportResult) {
getReportQuery({
variables: {
dateFrom: dateFrom,
dateTo: dateTo
}
})
} else {
if (currentUser && currentUser.role === 'lifebank') formatDataToLifebankReport()
else if (currentUser && currentUser.role === 'sponsor') formatDataToSponsorReport()
else return
}
}, [getReportQuery, currentUser, dateFrom, dateTo, getReportResult])
const formatDataToLifebankReport = () => {
const received = getReportResult.notifications.received.map((notification) => {
return [
notification.business,
notification.created_at_date,
notification.created_at_time,
notification.tokens
]
})
const sent = getReportResult.notifications.sent.map((notification) => {
return [
notification.send_to,
notification.created_at_date,
notification.created_at_time,
notification.tokens
]
})
setHeadReceived([
[
t('report.business'),
t('report.date'),
t('report.time'),
t('report.tokens')
]
]
)
setBodyReceive(received)
setBodySent(sent)
}
const formatDataToSponsorReport = () => {
const received = getReportResult.notifications.received.map((notification) => {
return [
notification.payerUser,
notification.offer ? notification.offer.offer_name : '',
notification.created_at_date,
notification.created_at_time,
notification.offer ? notification.offer.cost_in_tokens : '']
})
setHeadReceived([
[
t('report.user'),
t('report.offer'),
t('report.date'),
t('report.time'),
t('report.tokens')
]
]
)
setBodyReceive(received)
}
const downloadReport = () => {
const doc = new jsPDF()
const pageWidth = doc.internal.pageSize.getWidth()
const pageHeight = doc.internal.pageSize.getHeight()
if (currentUser && currentUser.role === 'lifebank') {
doc.autoTable({
margin: { top: 30, bottom: 30 },
pageBreak: 'auto',
head: headReceive,
body: bodyReceive
})
doc.autoTable({
margin: { top: 30, bottom: 30 },
pageBreak: 'auto',
head: headSent,
body: bodySent,
})
} else if (currentUser && currentUser.role === 'sponsor') {
doc.autoTable({
margin: { top: 30, bottom: 30 },
pageBreak: 'auto',
head: headReceive,
body: bodyReceive,
})
}
else return
for (let i = 1; i < doc.internal.pages.length; i++) {
doc.setPage(i)
doc.setFontSize(14)
doc.text(profile ? profile.name : '', pageWidth / 2, 10, { align: 'center' })
doc.text(new Date().toISOString().slice(0, 10), pageWidth / 2, 16, { align: 'center' })
if (dateFrom && dateTo) {
doc.text(
t('report.pdfHeader').concat(' ', t('report.from'), ' ', dateFrom, ' ', t('report.to'), ' ', dateTo),
pageWidth / 2, 22, { align: 'center' }
)
} else doc.text(t('report.pdfHeader'), pageWidth / 2, 22, { align: 'center' })
doc.text(t('report.pdfFooter'), pageWidth / 2, pageHeight - 20, { align: 'center', maxWidth: pageWidth - 50 })
}
doc.save(t('report.reportDownloadName'))
onReportSaved()
}
useEffect(() => {
if (saveReport) downloadReport()
}, [saveReport])
return (
<>
</>
)
}
Example #11
Source File: Settings.js From lifebank with MIT License | 4 votes |
Settings = ({ onCloseSetting }) => {
const { t } = useTranslation('translations')
const classes = useStyles()
const theme = useTheme()
const [user, setUser] = useState({})
const [openSnackbar, setOpenSnackbar] = useState(false)
const [open, setOpen] = useState(true)
const [showPassword, setShowPassword] = useState(false)
const [showNewPassword, setShowNewPassword] = useState(false)
const [validEmailFormat, setValidEmailFormat] = useState(false)
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const [currentUser, { logout }] = useUser()
const history = useHistory()
const [
loadProfile,
{ error: errorProfile, loading, data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const [
changePassword,
{ loading: loadingChangePassword, error: errorChangePassword, data: { change_password: responseChangePassword } = {} }
] = useMutation(CHANGE_PASSWORD)
const [
changeEmail,
{ loading: loadingChangeEmail, error: errorChangeEmail, data: { change_email: responseChangeEmail } = {} }
] = useMutation(CHANGE_EMAIL)
const [
updateEmailSubscription,
{ data: { update_user: updateEmailSubscriptionResult } = {} }
] = useMutation(UPDATE_EMAIL_SUBSCRIPTION_MUTATION)
const [
closeAccount,
{ loading: loadingCloseAccount, error: errorCloseAccount, data: { close_account: resultCloseAccount } = {} }
] = useMutation(CLOSE_ACCOUNT_MUTATION)
const [
getAccountSignupMethod,
{ data: { signup_method: getAccountSignupMethodResult } = {} }
] = useMutation(GET_ACCOUNT_SIGNUP_METHOD)
const handleCloseSnackBar = () => {
setOpenSnackbar({ ...openSnackbar, show: false })
}
const handleOpen = () => {
setOpen(!open)
onCloseSetting()
}
const handleClickShowPassword = () => {
setShowPassword(!showPassword)
}
const handleClickShowNewPassword = () => {
setShowNewPassword(!showNewPassword)
}
const handleSetField = (field, value) => {
setUser({ ...user, [field]: value })
}
const handleSetFieldEmail = (field, value) => {
const regularExpresion = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
if (regularExpresion.test(value)) setValidEmailFormat(true)
else setValidEmailFormat(false)
setUser({ ...user, [field]: value })
}
const handleSubmitChangePassword = async () => {
if (getAccountSignupMethodResult && getAccountSignupMethodResult.password_changable) {
changePassword({
variables: {
email: profile.email,
newPassword: user.newPassword,
currentPassword: user.currentPassword,
emailContent: {
subject: t('emailMessage.subjectChangePassword'),
title: t('emailMessage.titleChangePassword'),
message: t('emailMessage.messageChangePassword')
}
}
})
} else setOpenSnackbar({
show: true,
message: t('setting.passwordNotChangeable'),
severity: 'error'
})
}
const handleSubmitChangeEmail = async () => {
if (user && profile) {
changeEmail({
variables: {
account: profile.account,
email: user.email,
}
})
user.email = null
}
}
const handleChangeCheckBox = (event) => {
updateEmailSubscription({
variables: {
account: profile.account,
state: event.target.checked
}
})
}
const onCloseAccontClick = async () => {
setOpen(false)
await closeAccount()
}
useEffect(() => {
loadProfile()
}, [loadProfile, updateEmailSubscriptionResult])
useEffect(() => {
if (errorProfile)
setOpenSnackbar({
show: true,
message: t('credentialsRecovery.emailError'),
severity: 'error'
})
}, [errorProfile, t])
useEffect(() => {
if (errorChangeEmail)
setOpenSnackbar({
show: true,
message: t('setting.emailError'),
severity: 'error'
})
if (responseChangeEmail)
setOpenSnackbar({
show: true,
message: t('setting.emailChanged'),
severity: 'success'
})
loadProfile()
}, [t, loadProfile, changeEmail, errorChangeEmail, responseChangeEmail])
useEffect(() => {
if (responseChangePassword) {
if (responseChangePassword.success)
setOpenSnackbar({
show: true,
message: t('setting.passwordChanged'),
severity: 'success'
})
else
setOpenSnackbar({
show: true,
message: t('setting.passwordError'),
severity: 'error'
})
}
}, [t, responseChangePassword])
useEffect(() => {
if (errorChangePassword) {
if (errorChangePassword.message === `GraphQL error: Cannot read property 'secret' of null`)
setOpenSnackbar({
show: true,
message: t('credentialsRecovery.emailError'),
severity: 'error'
})
else setOpenSnackbar({
show: true,
message: errorChangePassword.message.replace('GraphQL error: ', ''),
severity: 'error'
})
}
}, [errorChangePassword, t])
useEffect(() => {
if (!currentUser) {
return
}
loadProfile()
}, [currentUser, loadProfile])
useEffect(() => {
if (profile) {
getAccountSignupMethod({
variables: {
email: profile.email
}
})
}
}, [getAccountSignupMethod, profile])
useEffect(() => {
if (resultCloseAccount) {
setOpen(false)
logout()
history.push('/')
}
}, [logout, history, resultCloseAccount])
useEffect(() => {
if (errorCloseAccount) {
setOpenSnackbar({
show: true,
message: t('setting.errorCloseAccount'),
severity: 'error'
})
}
}, [t, errorCloseAccount])
function executeCredentialsRecovery(e) {
if (e.key === 'Enter' && (user.newPassword && user.currentPassword)) {
e.preventDefault()
}
else if (e.key === 'Enter' && (!loading)) {
e.preventDefault()
}
}
function executeEmailChange(e) {
if (e.key === 'Enter' && validEmailFormat) {
e.preventDefault()
}
else if (e.key === 'Enter' && (!loading)) {
e.preventDefault()
}
}
return (
<>
<Dialog
open={open}
onClose={handleOpen}
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
fullScreen={fullScreen}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={handleOpen}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
<Box className={classes.textFieldWrapper}>
<Typography variant="h3" className={classes.title}>
{t('setting.setting')}
</Typography>
</Box>
<DialogContent className={classes.dimensions} >
<form autoComplete="off">
<Grid container>
<Grid container spacing={2}>
<Grid item xs={6}>
<Box className={classes.boxSecondVersion}>
<Typography variant="h3" className={classes.text}>
{t('setting.language')}
</Typography>
</Box>
<Box className={classes.boxSecondVersion}>
<LanguageSelector alt="settings" />
</Box>
</Grid>
<Divider orientation="vertical" flexItem />
<Grid item xs={5}>
<Box className={classes.boxSecondVersion}>
<Typography variant="h3" className={classes.text}>
{t('setting.suscribeSection')}
</Typography>
</Box>
<Box className={classes.checkBox}>
<FormControlLabel
disabled={loading}
checked={profile ? profile.email_subscription : true}
control={
<Checkbox
color="primary"
onChange={handleChangeCheckBox}
/>
}
label={t('setting.checkBoxSuscribe')}
labelPlacement="start"
/>
</Box>
</Grid>
</Grid>
<Grid container item xs={12}>
<Box className={classes.boxThirdVersion}>
<Divider className={classes.dividerSecondVersion} />
<Typography variant="h3" className={classes.text}>
{t('setting.changeEmail')}
</Typography>
<Grid item xs={12}>
<TextField
id="currentEmail"
variant="filled"
InputLabelProps={{ shrink: true }}
InputProps={{
endAdornment: (
<>
<InputLabel id="select-label">
{profile ? profile.email : ''}
</InputLabel>
</>
)
}}
onChange={(event) =>
handleSetFieldEmail('email', event.target.value)
}
onKeyPress={(event) =>
executeEmailChange(event)
}
className={classes.box}
>
</TextField>
</Grid>
<Box className={classes.box}>
<Button
disabled={(!validEmailFormat || !user.email) || loadingChangeEmail || loading}
variant="contained"
color="secondary"
onClick={handleSubmitChangeEmail}
className={classes.button}
>
{t('setting.changeEmail')}
</Button>
</Box>
<Box className={classes.loadingBox}>
{loadingChangeEmail && <CircularProgress />}
</Box>
</Box>
</Grid>
<Grid container item xs={12}>
<Box className={classes.box}>
<Divider className={classes.dividerSecondVersion} />
<Typography variant="h3" className={classes.text}>
{t('setting.changePassword')}
</Typography>
<Grid item xs={12}>
<TextField
id="currentPassword"
variant="filled"
type={showPassword ? 'text' : 'password'}
InputLabelProps={{ shrink: true }}
InputProps={{
endAdornment: (
<>
<InputLabel id="select-label">
{t('setting.currentPassword')}
</InputLabel>
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
edge="end"
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
</>
)
}}
value={user.currentPassword || ''}
onChange={(event) =>
handleSetField('currentPassword', event.target.value)
}
onKeyPress={(event) =>
executeCredentialsRecovery(event)
}
className={classes.box}
/>
</Grid>
<Grid item xs={12}>
<TextField
id="newPassword"
type={showNewPassword ? 'text' : 'password'}
variant="filled"
InputLabelProps={{ shrink: true }}
InputProps={{
endAdornment: (
<>
<InputLabel id="select-label">
{t('setting.newPassword')}
</InputLabel>
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowNewPassword}
edge="end"
>
{showNewPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
</>
)
}}
value={user.newPassword || ''}
onChange={(event) =>
handleSetField('newPassword', event.target.value)
}
onKeyPress={(event) =>
executeCredentialsRecovery(event)
}
className={classes.box}
/>
</Grid>
<Box>
<Button
disabled={(!user.newPassword || !user.currentPassword) || loadingChangePassword}
variant="contained"
color="secondary"
onClick={handleSubmitChangePassword}
className={classes.button}
>
{t('setting.changePassword')}
</Button>
</Box>
</Box>
</Grid>
<Grid container item xs={12}>
<Box className={classes.box}>
<Divider className={classes.dividerSecondVersion} />
<Typography variant="h3" className={classes.text}>
{t('setting.closeAccount')}
</Typography>
<Box>
<Button
disabled={loadingCloseAccount}
variant="contained"
color="secondary"
onClick={onCloseAccontClick}
className={classes.button}
>
{t('setting.closeAccountButton')}
</Button>
</Box>
<Box className={classes.loadingBox}>
{loadingCloseAccount && <CircularProgress />}
{loading && <CircularProgress />}
</Box>
</Box>
</Grid>
</Grid>
</form>
</DialogContent>
<Snackbar open={openSnackbar.show} autoHideDuration={4000} onClose={handleCloseSnackBar}>
<Alert
className={classes.alert}
severity={openSnackbar.severity}
>
{openSnackbar.message}
</Alert>
</Snackbar>
</Dialog>
</>
)
}
Example #12
Source File: DonationsDashboard.js From lifebank with MIT License | 4 votes |
DonationsDashboard = ({ isDesktop, currentUser, isOffer, selectOffer }) => {
const { t } = useTranslation('translations')
const [maxWidth] = useState('md')
const [maxWidthQr] = useState('xs')
const [open, setOpen] = useState(false)
const [accountTo, setAccountTo] = useState()
const [openModalQR, setOpenModalQR] = useState(false)
const [scanValue, setScanValue] = useState()
const [tokens, setTokens] = useState(0)
const [role] = useState(currentUser.role)
const [account] = useState(currentUser.account)
const classes = useStyles()
const [openSnackbar, setOpenSnackbar] = useState(false)
const [state, setState] = useState({
bottom: false
})
const theme = useTheme()
const isSmallScreen = useMediaQuery(theme.breakpoints.down(370))
const history = useHistory()
const [
loadProfile,
{ error: errroLoadProfile, data: { profile: { profile } = {} } = {}, client }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const { data: tokenUser = {} } = useSubscription(
TOKEN_SUBSCRIPTION, { variables: { account } }
)
const [
donate,
{ loading, error, data: { donate: donateResult } = {} }
] = useMutation(DONATE_MUTATION)
const handleSnackbarClose = () => {
setOpenSnackbar({ ...openSnackbar, show: false })
setAccountTo()
}
useEffect(() => {
if (!error)
return
setOpenSnackbar({
show: true,
message: t('donations.donationsError'),
severity: 'error'
})
}, [t, error])
useEffect(() => {
if (errroLoadProfile) {
handleOpen()
setOpenSnackbar({
show: true,
message: t('donations.donationsProfileError'),
severity: 'error'
})
}
}, [t, errroLoadProfile])
useEffect(() => {
if (!donateResult)
return
setOpenSnackbar({
show: true,
message: t('donations.succesful'),
severity: 'success'
})
}, [t, donateResult])
useEffect(() => {
if (!currentUser) {
client && client.resetStore()
history.replace('/')
return
}
if (state.bottom === true || open === true)
loadProfile()
}, [currentUser, history, client, loadProfile, state, open, donateResult])
useEffect(() => {
if (tokenUser.user) {
setTokens(parseInt(tokenUser.user[0].token))
} else {
setTokens(role === "donor" && profile?.balance.length ? profile.balance.join(',').split(' ')[0] : 0)
}
}, [role, profile, tokenUser])
const anchor = 'bottom'
const toggleDrawer = (anchor, open) => (event) => {
if (event) {
if (
event.type === 'keydown' &&
(event.key === 'Tab' || event.key === 'Shift')
)
return
setState({ ...state, [anchor]: open })
}
}
const handleOpen = () => setOpen(!open)
const handleOpenModalQr = () => setOpenModalQR(!openModalQR)
const handlerTransferTokens = (account) => {
setAccountTo(account)
}
useEffect(() => {
if (profile && accountTo) {
let tempMemo
if (role === "donor") tempMemo = t("donations.memoDonor")
else tempMemo = t("donations.memoLifebank")
const tokensQuantity = 1
const payload = {
to: accountTo.toLowerCase().replace(/\s/g, ''),
memo: tempMemo,
quantity: tokensQuantity,
emailContent: {
'subject': t('emailDonorCongratulation.subject'),
'content': t('emailDonorCongratulation.hi').concat(
' ',
accountTo,
', ',
'<br><br>',
t('emailDonorCongratulation.youComplete'),
' ',
profile.name,
' ',
t('emailDonorCongratulation.receivedTokens'),
' ',
tokensQuantity,
' ',
tokensQuantity > 1? t('emailDonorCongratulation.lifeTokensMany'): t('emailDonorCongratulation.lifeTokens'),
' ',
t('emailDonorCongratulation.thanksYou'),
'<br><br>',
t('emailDonorCongratulation.growingCommunity'),
),
"badge": t('emailDonorCongratulation.badgeUrl'),
"content2": t('emailDonorCongratulation.downloadBadge').concat(
'<br><br>',
t('emailDonorCongratulation.thanksAgain')
)
}
}
donate({
variables: {
...payload
}
})
}
}, [t, donate, role, accountTo])
const DashboardContent = () => {
const [accountInput, setAccountInput] = useState("")
const handleChangeAccountInput = (event) => {
setAccountInput(event.target.value)
}
useEffect(() => {
if (scanValue) setAccountInput(scanValue)
}, [scanValue])
return (
<Box className={classes.dashboardContent}>
{isDesktop && (
<>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={handleOpen}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
{role === "donor" &&
<Typography className={classes.draweTitleDesktop}>
{t('donations.donate')}
</Typography>
}
{role === "lifebank" &&
<Typography className={classes.draweTitleDesktop}>
{t('donations.transferTokens')}
</Typography>
}
{role === "sponsor" &&
<Typography className={classes.draweTitleDesktop}>
{t('donations.claimReward')}
</Typography>
}
</>
)}
{!isDesktop && (
<>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={toggleDrawer(anchor, false)}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
{role === "donor" &&
<Typography className={classes.draweTitle}>
{t('donations.yourDonationsAndRewards')}
</Typography>
}
{role === "lifebank" &&
<Typography className={classes.draweTitle}>
{t('donations.transferTokens')}
</Typography>
}
{role === "sponsor" &&
<Typography className={classes.draweTitle}>
{t('donations.claimReward')}
</Typography>
}
<Divider className={classes.dividerTitle} />
</>
)}
{role === "donor" &&
<Box className={classes.boxBalance}>
<Typography className={classes.balanceText}>
{t('donations.youOwn')}
</Typography>
<EmptyHeartSVG balance={parseInt(tokens)} isDesktop={isDesktop} />
<Typography className={classes.balanceText}>
{t('miscellaneous.tokens')}
</Typography>
</Box>
}
{ (role === "donor" || role === "sponsor") &&
<Box>
{role === "donor" &&
<Box>
<Typography className={classes.sectionTitle}>
{t('donations.receiveTokens')}
</Typography>
<Divider className={classes.dividerSection} />
<Typography className={classes.sectionText}>
{t('donations.toReceiveTokens')}
</Typography>
</Box>
}
{role === "sponsor" &&
<Typography className={classes.sectionText}>
{t('donations.toReceiveTokensDonor')}
</Typography>
}
<Box className={classes.boxQR}>
<QRCode value={account} size={100} />
<Typography className={classes.accountText}>
{account}
</Typography>
</Box>
</Box>
}
{ (role === "donor" || role === "lifebank") &&
<Box>
{role === "donor" &&
<Box>
<Typography className={classes.sectionTitle}>
{t('donations.sendTokens')}
</Typography>
<Divider className={classes.dividerSection} />
<Typography className={classes.sectionText}>
{t('donations.toSendTo')}
</Typography>
</Box>
}
{role === "lifebank" &&
<Typography className={classes.sectionText}>
{t('donations.toSendToDonor')}
</Typography>
}
<Box className={classes.boxTexfield}>
<form autoComplete="off">
<TextField
className={classes.inputText}
id="paylod-account"
label={role === "lifebank" ? t('donations.enterDonorUsername') : t('donations.enterSponsorUsername')}
variant="filled"
value={accountInput}
onChange={handleChangeAccountInput}
/>
<QrReaderModal setAccountInput={setAccountInput} />
</form>
</Box>
<Box className={classes.boxButtonSendToken}>
{loading &&
<>
<CircularProgress />
<br />
<br />
</>
}
<Button className={classes.sendTokenButton} variant="contained" color="secondary"
onClick={() => {
handlerTransferTokens(accountInput)
}}
disabled={
!accountInput ||
loading
}
>
{t('donations.sendToken')}
</Button>
</Box>
</Box>
}
</Box>
)
}
const Transition = forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />
})
const QrReaderModal = () => {
const theme = useTheme()
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const [cameraSelection, setCameraSelction] = useState("rear")
const succesefulScan = (value) => {
if (value) {
setOpenModalQR(false)
setScanValue(value)
}
}
useEffect(() => {
if (openModalQR) {
setScanValue("")
}
}, [openModalQR])
const handleChangeCamera = () => {
if (cameraSelection === "rear") setCameraSelction("front")
else setCameraSelction("rear")
}
return (
<>
<IconButton aria-label="delete" className={classes.camaraButtonIcon} onClick={handleOpenModalQr}>
<CameraAltIcon className={classes.camaraIcon} />
</IconButton>
<Dialog
fullScreen={fullScreen}
maxWidth={maxWidthQr}
open={openModalQR}
onClose={handleOpenModalQr}
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
TransitionComponent={Transition}
>
{fullScreen &&
<AppBar className={classes.appBar}>
<Toolbar>
<IconButton
className={classes.backIcon}
onClick={handleOpenModalQr}
aria-label="close"
>
<KeyboardBackspaceIcon />
</IconButton>
<Typography variant="h6" className={classes.titleScanQR}>
{t('donations.scanQR')}
</Typography>
<IconButton
className={classes.switchCamaraIcon}
onClick={handleChangeCamera}
aria-label="close"
>
<FlipCameraIosIcon />
</IconButton>
</Toolbar>
</AppBar>
}
{!fullScreen &&
<Box className={classes.dialog}>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={handleOpenModalQr}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
<Typography className={classes.titleScanQR}>
{t('donations.scanQR')}
</Typography>
</Box>
}
{cameraSelection &&
<QrReader
delay={100}
onError={() => { }}
onScan={(value) => { succesefulScan(value) }}
facingMode={cameraSelection}
style={{
height: "auto",
width: "100%",
backgroundColor: '#ffffff',
}}
/>
}
</Dialog>
</>
)
}
return (
<>
{!isDesktop && (
<>
{ role === "donor" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButton}
onClick={toggleDrawer(anchor, true)}
>
<FavoriteIcon className={classes.iconFab} />
{!isSmallScreen &&
t('donations.donate')
}
</Fab>
}
{ role === "lifebank" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButton}
onClick={toggleDrawer(anchor, true)}
>
<FavoriteIcon className={classes.iconFab} />
{!isSmallScreen &&
t('donations.transferTokens')
}
</Fab>
}
{ role === "sponsor" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButton}
onClick={toggleDrawer(anchor, true)}
>
<ShoppingCartIcon className={classes.iconFab} />
{!isSmallScreen &&
t('donations.claimReward')
}
</Fab>
}
<Drawer
anchor={anchor}
open={state[anchor]}
onClose={toggleDrawer(anchor, false)}
PaperProps={{
elevation: 0,
style: {
borderTopLeftRadius: '20px',
borderTopRightRadius: '20px',
padding: '16px',
}
}}
>
<DashboardContent />
</Drawer >
</>
)}
{isDesktop &&
<>
{
role === "donor" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButtonDesktop}
onClick={handleOpen}
>
<FavoriteIcon className={classes.iconFab} />
{t('donations.donate')}
</Fab>
}
{
role === "lifebank" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButtonDesktop}
onClick={handleOpen}
>
<FavoriteIcon className={classes.iconFab} />
{t('donations.transferTokens')}
</Fab>
}
{
role === "sponsor" && !isOffer &&
<Fab
color="secondary"
variant="extended"
className={classes.fabButtonDesktop}
onClick={handleOpen}
>
<ShoppingCartIcon className={classes.iconFab} />
{t('donations.claimReward')}
</Fab>
}
<Dialog
maxWidth={maxWidth}
open={open}
onClose={handleOpen}
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Box className={classes.dialog}>
<DashboardContent />
</Box>
</Dialog>
</>
}
<Snackbar open={openSnackbar.show} autoHideDuration={2000} onClose={handleSnackbarClose}>
<Alert severity={openSnackbar.severity}>
{openSnackbar.message}
</Alert>
</Snackbar>
</>
)
}
Example #13
Source File: ConsentComponent.js From lifebank with MIT License | 4 votes |
ConsetComponent = () => {
const [currentUser, { logout }] = useUser()
const { t } = useTranslation('translations')
const classes = useStyles()
const [openConsent, setOpenConsent] = useState(false)
const [openSnackbar, setOpenSnackbar] = useState(false)
const theme = useTheme()
const history = useHistory()
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const [maxWidthConset] = useState('sm')
const [
signup,
{ error: errorSignup, loading: signupLoading, data: { signup: signupResult } = {} }
] = useMutation(SIGNUP_MUTATION)
const [
loadProfile,
{ error: errorProfile, data: { profile: { profile } = {} } = {} }
] = useLazyQuery(PROFILE_QUERY, { fetchPolicy: 'network-only' })
const { refetch: accountName } = useQuery(GET_ACCOUNT_NAME, {
variables: {},
skip: true
})
const [editProfile] = useMutation(EDIT_PROFILE_MUTATION)
const handleOpenConsent = () => {
setOpenConsent(!openConsent)
}
const handleSingup = () => {
signup({
variables: {
profile
}
})
handleOpenConsent()
}
const handleCloseSnackbar = () => {
setOpenSnackbar({ ...openSnackbar, show: false })
}
const updateProfile = async () => {
const { data: { user } } = await accountName({ account: currentUser.account })
if (user.length > 0) {
const name = user[0].name
editProfile({
variables: {
profile: { name }
}
})
}
}
useEffect(() => {
if (currentUser) {
loadProfile()
}
}, [currentUser])
useEffect(() => {
if (currentUser && profile && !profile.consent) handleOpenConsent()
}, [profile, currentUser])
useEffect(() => {
if (signupResult) {
if (signupResult.success) {
if (profile.role === 'sponsor') updateProfile()
setOpenSnackbar({
show: true,
message: t('signup.consentGranted'),
severity: 'success'
})
} else {
setOpenSnackbar({
show: true,
message: t('signup.consentError'),
severity: 'error'
})
}
}
}, [t, signupResult, profile])
useEffect(() => {
if (errorProfile) {
logout()
history.replace('/reopen-account/' + currentUser.account)
}
if (errorSignup) {
setOpenSnackbar({
show: true,
message: t('signup.consentError'),
severity: 'error'
})
}
}, [t, logout, history, currentUser, errorSignup, errorProfile])
return (
<>
<Dialog
fullScreen={fullScreen}
maxWidth={maxWidthConset}
open={openConsent}
onClose={handleOpenConsent}
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Box className={classes.dialogConset}>
<Box className={classes.closeIcon}>
<IconButton
aria-label="close"
color="inherit"
size="small"
onClick={handleOpenConsent}
>
<CloseIcon fontSize="inherit" />
</IconButton>
</Box>
<Box>
<Box className={classes.stepperContent}>
<Typography className={classes.titleConsent}> {t('signup.termsAndConditions')}</Typography>
<Typography variant="body1" className={classes.textConsent}>{t('signup.termsAndConditionsInfo')}</Typography>
</Box>
<SignupAccount account={profile ? profile.account : ""} />
<SignupConsent onSubmit={handleSingup} loading={signupLoading} />
</Box>
</Box>
</Dialog>
<Snackbar open={openSnackbar.show} autoHideDuration={6000} onClose={handleCloseSnackbar}>
<Alert severity={openSnackbar.severity}>
{openSnackbar.message}
</Alert>
</Snackbar>
</>
)
}
Example #14
Source File: AcceptInvitation.jsx From saasgear with MIT License | 4 votes |
function AcceptInvitation() {
const { invitationToken } = useParams();
const [teamInfo, setTeamInfo] = useState(null);
const history = useHistory();
const [verify, { data, loading, error }] = useLazyQuery(verifyTokenQuery);
const {
data: userInfo,
error: getProfileError,
loading: getProfileLoading,
} = useQuery(getProfileQuery);
const [joinTeam] = useMutation(joinTeamQuery);
useEffect(() => {
if (!getProfileLoading && userInfo?.profileUser) {
if (userInfo?.profileUser) verify({ variables: { invitationToken } });
else history.replace(`/auth/signin?invitation=${invitationToken}`);
}
}, [getProfileError, userInfo]);
useEffect(() => {
if (!loading && data?.verifyInvitationToken) {
setTeamInfo(data.verifyInvitationToken);
}
if (error) {
history.push('/auth/signin');
}
}, [data, error, loading]);
async function handleUserJoinTeam(type) {
try {
await joinTeam({ variables: { token: invitationToken, type } });
history.replace('/');
} catch (e) {
console.error(e);
}
}
return loading && getProfileLoading ? (
<div> Loading ....</div>
) : (
<ForgotPasswordWrapper>
<Overlay />
<ForgotPasswordContainer>
<div>
<Logo />
</div>
<ForgotPasswordText>Accept Invitation?</ForgotPasswordText>
<ForgotPasswordDescription>
You' ve been invitated to join{' '}
<strong>{teamInfo?.teamName}</strong> by{' '}
<strong>{teamInfo?.owner}</strong>
</ForgotPasswordDescription>
<ButtonGroup>
<Button color="primary" onClick={() => handleUserJoinTeam('accept')}>
Accept
</Button>
<Button onClick={() => handleUserJoinTeam('decline')}>Decline</Button>
</ButtonGroup>
<SquareIconTop>
<svg
width="496"
height="482"
viewBox="0 0 496 482"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 1H445C472.614 1 495 23.3858 495 51V481H50C22.3858 481 0 458.614 0 431V1Z"
stroke="#2291FF"
/>
</svg>
</SquareIconTop>
<SmallSquareBottom>
<svg
width="195"
height="195"
viewBox="0 0 195 195"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0H145C172.614 0 195 22.3858 195 50V195H50C22.3858 195 0 172.614 0 145V0Z"
fill="#0075E8"
/>
</svg>
</SmallSquareBottom>
<SmallSquareTop>
<svg
width="114"
height="121"
viewBox="0 0 114 121"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0H64C91.6142 0 114 22.3858 114 50V121H50C22.3858 121 0 98.6142 0 71V0Z"
fill="#1788F8"
/>
</svg>
</SmallSquareTop>
<SmallSquareGrid>
<svg
width="131"
height="123"
viewBox="0 0 131 123"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g opacity="0.5">
<path
d="M129.844 121.5H1"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
strokeDasharray="1 40"
/>
<path
d="M129.844 81.5H1"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
strokeDasharray="1 40"
/>
<path
d="M129.844 41.5H1"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
strokeDasharray="1 40"
/>
<path
d="M129.844 1.5H1"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
strokeDasharray="1 40"
/>
</g>
</svg>
</SmallSquareGrid>
<SquareIconBottom>
<svg
width="594"
height="523"
viewBox="0 0 594 523"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 1H544C571.614 1 594 23.3858 594 51V529H51C23.3858 529 1 506.614 1 479V1Z"
stroke="#2291FF"
/>
</svg>
</SquareIconBottom>
<CircleIcon>
<svg
width="60"
height="60"
viewBox="0 0 60 60"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="30" cy="30" r="29" stroke="#2291FF" />
</svg>
</CircleIcon>
</ForgotPasswordContainer>
</ForgotPasswordWrapper>
);
}
Example #15
Source File: PlanSetting.jsx From saasgear with MIT License | 4 votes |
PlanSetting = () => {
const [isYearly, setIsYearly] = useState(false);
const [selectedPlan, setSelectedPlan] = useState('');
const { data: currentPlan } = useSelector((state) => state.userPlan);
const [deleteUserPlanMutation, { error: errorDelete, loading: isDeletingUserPlan }] = useMutation(deleteUserPlanQuery);
const [updateUserPlanMutation, { error: errorUpdate, loading: isUpdatingUserPlan }] = useMutation(updateUserPlanQuery);
const [createUserPlanMutation, { error: errorCreate, loading: isCreatingUserPlan }] = useMutation(createUserPlanQuery);
const [fetchUserPlan, { data: userPlanData }] = useLazyQuery(getUserPlanQuery);
const dispatch = useDispatch();
useEffect(() => {
if (!isEmpty(currentPlan)) {
setSelectedPlan(currentPlan.productType);
setIsYearly(currentPlan.priceType === 'yearly');
}
}, [currentPlan])
useEffect(() => {
if (userPlanData?.getUserPlan) {
dispatch(setUserPlan({ data: userPlanData?.getUserPlan }));
}
}, [userPlanData])
function toggle() {
setIsYearly(!isYearly);
}
function changePlan(name) {
setSelectedPlan(name);
}
function checkIsCurrentPlan(planId) {
return currentPlan.productType === planId && ((currentPlan.priceType === 'monthly' && !isYearly) || (currentPlan.priceType === 'yearly' && isYearly))
}
async function handleCancelSubscription() {
await deleteUserPlanMutation({
variables: { userPlanId: currentPlan.id }
});
fetchUserPlan();
}
async function createPaymentMethodSuccess(token) {
const data = {
paymentMethodToken: token,
planName: planChanged.id,
billingType: isYearly ? 'YEARLY' : 'MONTHLY',
}
await createUserPlanMutation({ variables: data});
fetchUserPlan();
}
async function handleChangeSubcription() {
await updateUserPlanMutation({ variables: {
userPlanId: currentPlan.id,
planName: planChanged.id,
billingType: isYearly ? 'YEARLY' : 'MONTHLY',
}});
fetchUserPlan();
}
const planChanged = !!selectedPlan && plans.find(item => item.id === selectedPlan) || {};
const amountCurrent = currentPlan.amount || 0;
const amountNew = planChanged ? planChanged.price : 0;
return (
<ContentPage>
<TitleContentStyle>Plan</TitleContentStyle>
<Description>This is your subscription</Description>
<Content>
<LeftContent>
<ToggleYearly>
<Toggle onChange={toggle} label="Bill Yearly" />
</ToggleYearly>
<Plans
plans={plans}
onChange={changePlan}
planChanged={planChanged}
isYearly={isYearly}
checkIsCurrentPlan={checkIsCurrentPlan}
/>
</LeftContent>
{!isEmpty(planChanged) && (
<RightContent>
{checkIsCurrentPlan(planChanged.id) ? (
<CurrentPlanWrapper>
{currentPlan.deletedAt ? (
<p>Plan will expire on <b>{dayjs(currentPlan.expiredAt).format('YYYY-MM-DD HH:mm')}</b></p>
) : (
<Button
color="primary"
disabled={isDeletingUserPlan}
onClick={handleCancelSubscription}
>Cancel Subcription</Button>
)}
</CurrentPlanWrapper>
) : (
<PaymentWrapper>
<SummaryTitle>Order Summary</SummaryTitle>
<AmountList>
<AmountItem>
<AmoutText>Current subcription</AmoutText>
<Amount>${amountCurrent}</Amount>
</AmountItem>
<AmountItem>
<AmoutText>New subcription</AmoutText>
<Amount>${isYearly ? amountNew * 9 : amountNew}</Amount>
</AmountItem>
<AmountItem>
<AmoutText>Balance due right now</AmoutText>
<Amount>${Math.max((isYearly ? amountNew * 9 : amountNew) - amountCurrent, 0)}</Amount>
</AmountItem>
</AmountList>
{(isEmpty(currentPlan) || (currentPlan && currentPlan.deletedAt)) ? (
<StripeContainer
onSubmitSuccess={createPaymentMethodSuccess}
apiLoading={isCreatingUserPlan}
submitText={currentPlan && currentPlan.deletedAt && 'Change plan'}
/>
) : (
<Button
color="primary"
onClick={handleChangeSubcription}
disabled={isUpdatingUserPlan}
>{isUpdatingUserPlan ? 'Please wait' : 'Change Subcription'}</Button>
)}
</PaymentWrapper>
)}
{errorCreate?.message && (
<ErrorText message={errorCreate.message} />
)}
{errorUpdate?.message && (
<ErrorText message={errorUpdate.message} />
)}
{errorDelete?.message && (
<ErrorText message={errorDelete.message} />
)}
</RightContent>
)}
</Content>
</ContentPage>
);
}
Example #16
Source File: Action.jsx From saasgear with MIT License | 4 votes |
ActionDocument = () => {
const match = useRouteMatch();
const history = useHistory();
const documentId = parseInt(match.params.id, 10);
const { handleSubmit, control, register, errors, setValue } = useForm({
resolver: yupResolver(ActionDocumentSchema),
mode: 'onChange',
});
const [
createDocumentMutation,
{ loading: isCreating, error: createError },
] = useMutation(createDocumentQuery);
const [
updateDocumentMutation,
{ loading: isUpdating, error: updateError },
] = useMutation(updateDocumentQuery);
const [fetchDocumentDetail, { data: documentData }] = useLazyQuery(
getDocumentDetailQuery,
);
const [editorContent, setEditorContent] = useState('');
useEffect(() => {
if (documentId) {
fetchDocumentDetail({ variables: { id: documentId } });
}
}, [documentId]);
useEffect(() => {
if (documentData?.getDocumentDetail) {
const values = documentData.getDocumentDetail;
setValue('name', values.name);
setEditorContent(values.body);
}
}, [documentData]);
async function onSubmit(data) {
if (documentId) {
await updateDocumentMutation({
variables: {
...data,
id: documentId,
},
});
} else {
await createDocumentMutation({ variables: data });
}
if (!createError && !updateError) {
history.push('/document');
}
}
return (
<div>
<Header>
<TitlePageStyle>
{documentData?.getDocumentDetail?.name
? documentData.getDocumentDetail.name
: 'New Document'}
</TitlePageStyle>
<SaveBtn
color="primary"
onClick={handleSubmit(onSubmit)}
disabled={isCreating || isUpdating}
>
{isCreating || isUpdating ? 'Please wait' : 'Save'}
</SaveBtn>
</Header>
<ContentPage>
<DocumentForm
editorContent={editorContent}
onSubmit={handleSubmit(onSubmit)}
control={control}
register={register}
isSubmitting={isCreating || isUpdating}
formErrors={errors}
apiError={createError?.message || updateError?.message}
/>
</ContentPage>
</div>
);
}
Example #17
Source File: LocationsPage.jsx From trashpanda-fe with MIT License | 4 votes |
LocationsPage = ({ theme }) => {
const { materialId } = useParams();
const [zip, setZip] = useState("");
const [loading, setLoading] = useState(false);
const [locations, setLocations] = useState([]);
const gps = JSON.parse(localStorage.getItem("gps"));
const [getLocations, locationInfo] = useLazyQuery(GET_LOCATIONS);
const [getPostal, postalInfo] = useLazyQuery(GET_POSTAL);
const [getZip, zipInfo] = useLazyQuery(GET_ZIP);
useEffect(() => {
if (gps) {
const { latitude, longitude } = gps;
//Set zip code field to contain current users zip code location
getZip({
variables: {
latitude: latitude.toString(),
longitude: longitude.toString()
}
});
//Search for nearby centers automatically
setLoading(true);
getLocations({
variables: {
latitude,
longitude,
material_id: parseInt(materialId)
}
});
}
}, [location]);
useEffect(() => {
if (zipInfo.called && zipInfo.data) {
setZip(zipInfo.data.getZip.postal_code.slice(0, 5));
}
}, [zipInfo]);
useEffect(() => {
if (postalInfo.called && postalInfo.data) {
const { longitude, latitude } = postalInfo.data.postal_code;
getLocations({
variables: {
latitude,
longitude,
material_id: parseInt(materialId)
}
});
}
//invalid postal_codes still return objects but nothing that is resolved by our backend
if (
!postalInfo.loading &&
postalInfo.postal_code !== 0 &&
!locationInfo.loading &&
locationInfo.called
) {
setLoading(false);
}
}, [postalInfo]);
useEffect(() => {
if (locationInfo.called && locationInfo.data && !locationInfo.loading) {
setLocations(locationInfo.data.locations);
setLoading(false);
}
}, [locationInfo.loading, locationInfo.called, locationInfo.data]);
const handleClick = () => {
if (
postalInfo.variables &&
postalInfo.variables.postal_code &&
postalInfo.variables.postal_code === zip
) {
return;
}
if (validateZip(zip)) {
setLoading(true);
console.log("Searching for ", zip);
getPostal({
variables: {
postal_code: zip
}
});
} else alert("Please enter a valid 5-digit US zip code");
};
const handleKeyDown = e => {
if (e.key === "Enter") if (zip.length >= 5) handleClick();
};
return (
<Container>
<Blurb>Where can I bring this?</Blurb>
<ZipSearchBar
handleClick={handleClick}
value={zip}
onChange={e => setZip(e.target.value)}
btnDisabled={zip.length < 5 || loading}
onKeyDown={handleKeyDown}
/>
{loading ? (
<Spinner />
) : (
renderLocations(locations, locationInfo.called, theme)
)}
</Container>
);
}