react-apollo#useQuery JavaScript Examples
The following examples show how to use
react-apollo#useQuery.
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: index.js From AdaptivApps-fe with MIT License | 6 votes |
export default function EventsCalendar() {
const classes = useStyles();
const { loading, error, data, refetch } = useQuery(GET_EVENT_LIST);
// refetches EVENT_LIST without refreshing page
useEffect(() => {
refetch();
}, [refetch]);
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography className={classes.heading} variant="h1" gutterBottom>
Upcoming Events
</Typography>
</Box>
<Grid className={classes.grid}>
{data &&
data?.events?.map((event, id) => (
<EventCard key={id} event={event} />
))}
</Grid>
</main>
);
}
Example #2
Source File: index.js From AdaptivApps-fe with MIT License | 6 votes |
ManageEvents = () => {
const classes = useStyles();
// Getting all events
const { data: eventsData, refetch: eventsRefetch } = useQuery(GET_EVENTS);
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography className={classes.heading} variant="h1" gutterBottom>
Manage Events
</Typography>
</Box>
<Box>
{/* Call the AdminEventList, which will contain a list of events */}
{eventsData ? (
<AdminEventList
events={eventsData?.events}
eventsRefetch={eventsRefetch}
/>
) : (
<CircularProgress className={classes.loadingSpinner} />
)}
</Box>
</main>
);
}
Example #3
Source File: index.js From AdaptivApps-fe with MIT License | 6 votes |
export default function MyEventDetails() {
const classes = useStyles();
// Retrieves ID of current event from parameters
const { eventId } = useParams();
// Retrieves logged in user info from Auth0
const { user } = useAuth0();
// Retrieves event details of specified event by ID which user is registered to
const { loading, error, data, refetch } = useQuery(GET_EVENT_DETAILS, {
variables: { id: eventId, email: user.email },
});
useEffect(() => {
refetch();
}, [refetch]);
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
const activeEvent = data.events;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Link href="/myevents" className={classes.linkBack}>
<ArrowBackIosIcon color="primary" fontSize="large" />
Back to my events
</Link>
<Typography variant="h1" gutterBottom>
Event Details
</Typography>
</Box>
{activeEvent &&
activeEvent.map((event, id) => <EventDetails key={id} event={event} />)}
</main>
);
}
Example #4
Source File: index.js From AdaptivApps-fe with MIT License | 6 votes |
UserProfile = () => {
const { user } = useAuth0();
const [createProfile] = useMutation(ADD_USER_PROFILE);
const [updateProfile] = useMutation(UPDATE_USER_PROFILE);
// Fetch profile for the user using the email associated with auth0 login
const { loading, error, data } = useQuery(PROFILE_INFO, {
variables: { email: user && user.email },
});
const profile = data && data.profile;
// Extract the profile from returning data of useQuery
useEffect(() => {
if (error) {
return <p>Error</p>;
}
// If user does not have a profile in backend, create one for them
if (!loading && !profile) {
newProfile();
}
// eslint-disable-next-line
}, [profile]);
// Function that creates a profile for given email
const newProfile = async () => {
await createProfile({ variables: { email: user.email } });
};
return (
<ProfileForm
loading={loading}
profile={profile ? profile : null}
user={user}
updateProfile={updateProfile}
/>
);
}
Example #5
Source File: index.js From AdaptivApps-fe with MIT License | 5 votes |
export default function ActivityList() {
const classes = useStyles();
const { eventId } = useParams();
const { loading, error, data: activityData } = useQuery(
GET_EVENT_ACTIVITIES,
{
variables: { id: eventId },
}
);
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography className={classes.heading} variant="h1" gutterBottom>
Event Activities
</Typography>
</Box>
<Box className={classes.eventContainer}>
<Box className={classes.imgContainer}>
<img
className={classes.eventImg}
src={activityData && activityData?.event?.imgUrl}
alt="Event"
/>
</Box>
<Box className={classes.infoContainer}>
<Typography
className={classes.date}
variant="body2"
color="textSecondary"
component="p"
>
{activityData.event.startDate}-{activityData.event.endDate}
</Typography>
<Typography className={classes.title}>
{activityData.event.title}
</Typography>
<Typography
className={classes.loc}
variant="body2"
color="textSecondary"
component="p"
>
{activityData.event.location}
</Typography>
</Box>
</Box>
<Box className={classes.details}>{activityData.event.details}</Box>
{activityData.event.activities.length >= 1 ? (
<Box className={classes.activityC}>
<p>Activities Schedule</p>
<table className={classes.table}>
<tbody>
<tr className={classes.headerRow}>
<th className={classes.tableH}>Name</th>
<th className={classes.tableH}>Date</th>
{activityData.event.type === "In Person" ? (
<th className={classes.tableH}>Location</th>
) : null}
<th className={classes.tableH}>Time</th>
</tr>
{activityData &&
activityData?.event?.activities.map((activity, id) => (
<Activities
key={id}
activity={activity}
activityData={activityData}
/>
))}
</tbody>
</table>
</Box>
) : null}
</main>
);
}
Example #6
Source File: UsersList.js From AdaptivApps-fe with MIT License | 5 votes |
UsersList = () => {
const classes = useStyles();
const { data } = useQuery(GET_PROFILES);
return (
<Container className={classes.root} m="0 2% 0 2%">
<MaterialTable
title="Registered Users"
data={data?.profiles}
columns={[
{ title: "Firstname", field: "firstName" },
{ title: "Lastname", field: "lastName" },
{ title: "Birthday", field: "birthday" },
{ title: "Disability", field: "disability" },
{ title: "Legal Status", field: "legal" },
]}
options={{
selection: true,
search: true,
showTitle: false,
paging: true,
emptyRowsWhenPaging: false,
filtering: true,
cellStyle: {
fontSize: "1.2rem",
},
headerStyle: {
fontSize: "1.2rem",
},
}}
actions={[
{
tooltip: "Send a message to all selected users",
icon: "message",
onClick: (evt, data) =>
alert("Send messages to " + data.length + " users?"),
},
]}
/>
</Container>
);
}
Example #7
Source File: index.js From AdaptivApps-fe with MIT License | 5 votes |
export default function MyEvents() {
const classes = useStyles();
// Retrieves logged in user info
const { user } = useAuth0();
// Retrieves all events a user is registered to
const { error, loading, data, refetch } = useQuery(GET_USER_EVENTS, {
variables: { email: user.email },
});
useEffect(() => {
refetch();
}, [refetch]);
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography className={classes.heading} variant="h1" gutterBottom>
My Events
</Typography>
</Box>
{data.events.length >= 1 ? (
<Grid className={classes.grid}>
{data &&
data?.events?.map((event, id) => (
<MyEventCard key={id} event={event} refetch={refetch} />
))}
</Grid>
) : (
<>
<Typography className={classes.noActiv}>
You haven't registered for any events yet!
</Typography>
<Box className={classes.inlineNotice}>
<Typography className={classes.noActivBlue}>
Check out the Events Calendar
</Typography>
<Typography>
, register for an event, then see all of your registered events
here!
</Typography>
</Box>
</>
)}
</main>
);
}
Example #8
Source File: ViewAllBusiness.panel.jsx From dineforward with MIT License | 5 votes |
AddRestaurantPanel = props => {
const classes = useStyles();
// const [addBizRequest, { data, loading, error }] = useMutation(CREATE_BIZ, {
// onCompleted: data => console.log(`completed - ${data}`),
// onError: error => console.log(`error - ${error}`),
// });
const { loading, error, data } = useQuery(VIEW_ALL_BUINESSES, gqlEvents);
const [place, setPlace] = React.useState({});
const [businessInfo, setBusinessInfo] = React.useState({});
if (loading) return <b>Loading...</b>;
if (error) return <b>Error - {error}</b>;
if (!error && !loading && data) {
return (
<Box className={classes.panel}>
<div className={classes.panelContent}>
<Grid container spacing={5}>
<Grid item md={12}>
<Typography variant="h3">All businesses</Typography>
<Link href="businesses/new">
<a>
<button>Add a new business</button>
</a>
</Link>
</Grid>
<Grid item md={12}>
<MaterialTable
data={data.allBusinesses}
columns={[
{ title: 'Name', field: 'name' },
{ title: 'Status', field: 'status' },
{ title: 'Location', field: 'location.formattedAddress' },
{ title: 'Backers', field: '_backersMeta.count', type: 'numeric' },
{ title: 'Staff Count', field: '_staffMembersMeta.count', type: 'numeric' },
]}
title="Your businesses"
/>
</Grid>
</Grid>
</div>
</Box>
);
}
}
Example #9
Source File: InfoBar.js From AdaptivApps-fe with MIT License | 4 votes |
function InfoBar({ user, setAlertOpen, setNewRoom, setDeleteRoom }) {
const classes = useStyles();
const [open, setOpen] = useState(false);
const [announcement, setAnnouncementOpen] = useState(false);
const [searchRecipient, setSearchRecipient] = useState("");
const [results, setResults] = useState([]);
const { loading, error, data, refetch, subscribeToMore } = useQuery(GET_CHAT_ROOMS, { variables: { email: user.email } });
const { data: recipients } = useQuery(GET_RECIPIENTS);
const { data: announcements } = useQuery(GET_ANNOUNCEMENTS, { variables: { isAnnouncementRoom: true } });
const { data: chats, refetch: refetchProfile } = useQuery(GET_USER_PROFILE, { variables: { email: user.email } });
// Chat Room Subscription
const _subscribeToNewChatRoom = subscribeToMore => {
subscribeToMore({
document: CHAT_ROOM_SUBSCRIPTION,
updateQuery: (prev, {subscriptionData }) => {
if (!subscriptionData.data) return prev
const chatRoom = subscriptionData.data.chatRoom
refetch();
refetchProfile();
return Object.assign({}, prev, {
profile: {
chatRooms: [chatRoom, ...prev.profile.chatRooms],
__typename: prev.profile.__typename
}
})
}
})
};
_subscribeToNewChatRoom(subscribeToMore);
// Convert announcement object to Array & filter out notifications
const announcementArray = announcements && Object.values(announcements)
const notifications = announcementArray && announcementArray.map(ann => {
return ann.filter(item => item.notification.length > 0 && item.notification)})
// Make sure no participants pass through with a null or empty name
const validParticipants = [];
recipients && recipients.profiles.map(user => {
if (user.firstName !== null && user.lastName !== null &&
user.firstName !== '' && user.lastName !== '') {
validParticipants.push(user);
};
});
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
// Load a user's chat rooms via participant names
const participants = data && data?.profile.chatRooms.map(item => item !== null && item.participants).concat().flat();
// Search for a chat room
const searchRooms = e => {
e.preventDefault();
let filter = data && data?.profile.chatRooms.map(room => {
let users = room.participants.map(user => {
if (user.firstName !== null && user.lastName !== null &&
user.firstName !== '' && user.lastName !== '') {
return `${user.firstName.toLowerCase()} ${user.lastName.toLowerCase()}`;
}});
return users.filter(user => {
if (user.includes(searchRecipient.toLowerCase())) {
results.push(room);
return results;
} else if (searchRecipient === "all" || searchRecipient === "All") {
return participants;
};
});
});
setSearchRecipient('');
};
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const handleChange = e => {
setResults([]);
setSearchRecipient(e.target.value);
};
const handleAnnouncementOpen = () => {
setAnnouncementOpen(true);
};
const handleAnnouncementClose = () => {
setAnnouncementOpen(false);
};
return (
<div className={classes.root}>
<h1 className={classes.header}>Messages</h1>
<div className={classes.messageIcons}>
<CreateIcon className={classes.icons} onClick={handleOpen} />
<span className={classes.span} onClick={handleOpen} aria-label="New Message Button">New Message</span>
</div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}>
<RecipientModal user={user} setOpen={setOpen} setNewRoom={setNewRoom} participants={participants} validParticipants={validParticipants} />
</Modal>
{user && user[config.roleUrl].includes("Admin") ?
(
<>
<div className={classes.messageIcons}>
<LanguageIcon className={classes.icons} /><span className={classes.span} onClick={handleAnnouncementOpen} aria-label="New Announcement Button">New Announcement</span>
</div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={announcement}
onClose={handleAnnouncementClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}>
<AnnouncementModal user={user} validParticipants={validParticipants} setAnnouncementOpen={setAnnouncementOpen} setAlertOpen={setAlertOpen} />
</Modal>
</>
) : null}
<div className={classes.chatRoomDiv}>
<AnnouncementRoom notifications={notifications} key='announcement_room' user={user} chats={chats}/>
<Divider variant="inset" className={classes.divider} />
{results.length > 0 ?
(results.map((chatRoom, id) => (
<div className={classes.chatroom} key={id}>
<ChatRoom chatRoom={chatRoom} user={user} setDeleteRoom={setDeleteRoom} chats={chats}/>
<Divider variant="inset" className={classes.divider} />
</div>
)))
:
(data.profile.chatRooms === undefined ? null :
(data && data?.profile.chatRooms?.map((chatRoom, id) => (
<div className={classes.chatroom} key={id}>
<ChatRoom chatRoom={chatRoom} user={user} setDeleteRoom={setDeleteRoom} chats={chats} />
<Divider variant="inset" className={classes.divider} />
</div>
))))
}
</div>
<Tooltip title="Type 'all' or 'All' to clear search results">
<Box component="div" className={classes.box}>
<TextField
className={classes.searchBox}
variant="outlined"
type="text"
name="message"
placeholder="Search Messages..."
aria-label="Search Chatrooms"
value={searchRecipient}
onChange={handleChange}
InputProps={{
endAdornment:
<InputAdornment position="end">
<IconButton onClick={searchRooms} aria-label="Search Chatrooms">
<SearchIcon fontSize="large" />
</IconButton>
</InputAdornment>
}} />
</Box>
</Tooltip>
</div>
)
}
Example #10
Source File: Announcements.js From AdaptivApps-fe with MIT License | 4 votes |
export default function Announcements({ user, setUpdateChat, setDeleteChat }) {
const classes = useStyles();
const [announcementOpen, setAnnouncementOpen] = useState(false);
const [announcementToEdit, setAnnouncementToEdit] = useState();
const [deleteAnnouncement] = useMutation(DELETE_ANNOUNCEMENT);
const { loading, error, data } = useQuery(GET_ANNOUNCEMENTS, { variables: { isAnnouncementRoom: true } });
const announcements = data && data?.announcements?.map((announcement) => {return {
id: announcement.id,
title: announcement.title,
message: announcement.message,
createdAt: announcement.createdAt,
notification: announcement.notification
}
});
// Sets up an auto-scroll to last announcement when new announcement received, or when an announcement is updated/deleted
const announcementsEndRef = useRef(null)
const scrollToBottom = () => {
announcementsEndRef.current && announcementsEndRef.current.scrollIntoView({ behavior: "smooth" });
};
useEffect(() => {
scrollToBottom()
}, [announcements]);
const handleClose = () => {
setAnnouncementOpen(false);
};
// Delete an announcement
const deleteMessage = async (announcement) => {
await deleteAnnouncement({
variables: { id: announcement.id }
});
setDeleteChat(true);
};
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
return (
<div className={classes.root}>
<div className={classes.messageDiv}>
{announcements.map((announcement) => (
<>
<div key={announcement.id} className={classes.messageBox}>
<div className={classes.userMessage}>
<div className={classes.messageHeader}>
<p className={classes.sender}>{announcement.title}</p>
{user && user[config.roleUrl].includes("Admin") ? (
<div className={classes.iconDiv}>
<Tooltip title="Edit Announcement">
<EditOutlinedIcon className={classes.editIcon} onClick={() => {setAnnouncementOpen(true); setAnnouncementToEdit(announcement)}} />
</Tooltip>
<Tooltip title="Delete Announcement">
<DeleteIcon className={classes.deleteIcon} onClick={() => deleteMessage(announcement)} />
</Tooltip>
</div>) : null}
</div>
<p className={classes.messageText}>{announcement.message}</p>
<div ref={announcementsEndRef} />
</div>
</div>
</>
))}
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={announcementOpen}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}>
<EditAnnouncementModal setAnnouncementOpen={setAnnouncementOpen} announcement={announcementToEdit} setUpdateChat={setUpdateChat} />
</Modal>
</div>
</div>
)
}
Example #11
Source File: AdminActivityList.js From AdaptivApps-fe with MIT License | 4 votes |
AdminActivityList = props => {
const classes = useStyles();
// Grab the event id from props
const event_id = props.event_id;
// Call backend to fetch the one event associated with event id
const { data, refetch } = useQuery(GET_ONE_EVENT, {
variables: {
id: event_id,
},
});
// Declares C, U, and D for activities
const [CreateActivity] = useMutation(CREATE_ACTIVITY);
const [UpdateActivity] = useMutation(UPDATE_ACTIVITY);
const [DeleteActivity] = useMutation(DELETE_ACTIVITY);
// Similar to its parent component, activities list will be displayed
// Using material table.
return (
<Grid>
<MaterialTable
title=""
columns={[
{
title: "Name",
field: "name",
editComponent: props => (
<>
<Input
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
<InputLabel className={classes.label}>*Required</InputLabel>
</>
),
},
{
title: "Date",
field: "startDate",
editComponent: props => (
<>
<Input
type="date"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
<InputLabel className={classes.label}>*Required</InputLabel>
</>
),
},
{
title: "Time",
field: "startTime",
editComponent: props => (
<>
<Input
type="time"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
<InputLabel className={classes.label}>*Required</InputLabel>
</>
),
},
{
title: "Location",
field: "location",
editComponent: props => (
<Input
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
),
},
{
title: "Link",
field: "link",
render: rowData => (
<div
style={{
fontSize: "1.4rem",
width: "22rem",
overflow: "scroll",
}}
>
{rowData.link}
</div>
),
editComponent: props => (
<Input
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
),
},
{
title: "Type",
field: "type",
editComponent: props => (
<Input
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
),
},
{
title: "Details",
field: "details",
render: rowData => (
<div
style={{
fontSize: "1.4rem",
width: "30rem",
maxHeight: "13rem",
overflow: "scroll",
}}
>
{rowData.details}
</div>
),
editComponent: props => (
<textarea
style={{
fontSize: "1.4rem",
}}
rows="7"
cols="60"
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}
/>
),
},
]}
data={data?.event?.activities}
editable={{
onRowAdd: async newData => {
await CreateActivity({
variables: {
name: newData.name,
startDate: newData.startDate,
startTime: newData.startTime,
location: newData.location,
link: newData.link,
type: newData.type,
details: newData.details,
event_id: event_id,
},
});
refetch();
},
onRowUpdate: async (newData, oldData) => {
await UpdateActivity({
variables: {
id: oldData.id,
name: newData.name,
startDate: newData.startDate,
startTime: newData.startTime,
location: newData.location,
link: newData.link,
type: newData.type,
details: newData.details,
},
});
refetch();
},
onRowDelete: async oldData => {
await DeleteActivity({
variables: {
id: oldData.id,
},
});
refetch();
},
}}
icons={{
Add: () => (
<>
<AddCircleOutlineIcon
style={{ color: "#2962FF" }}
fontSize="large"
/>
<Button className={classes.addBtn}>Add Activity</Button>
</>
),
Edit: () => (
<EditIcon style={{ color: "#2962FF" }} fontSize="large" />
),
Delete: () => (
<DeleteIcon style={{ color: "#2962FF" }} fontSize="large" />
),
}}
options={{
cellStyle: {
fontSize: "1.4rem",
},
headerStyle: {
fontSize: "3.4rem",
backgroundColor: "#2962FF",
color: "#FFF",
},
search: false,
showTitle: true,
paging: false,
emptyRowsWhenPaging: false,
toolbarButtonAlignment: "left",
}}
/>
</Grid>
);
}
Example #12
Source File: EventDetails.js From AdaptivApps-fe with MIT License | 4 votes |
export default function EventDetails(props) {
const classes = useStyles();
const activeEvent = props.event;
const eventId = activeEvent.id;
const { user } = useAuth0();
const { loading, error, data, refetch } = useQuery(GET_USER_ACTIVITIES, {
variables: { id: eventId, email: user.email },
});
useEffect(() => {
refetch();
}, [refetch]);
if (loading) return <CircularProgress className={classes.loadingSpinner} />;
if (error) return `Error! ${error.message}`;
const currentActivities = data.activities;
return (
<Box className={classes.root} m={4}>
<Box className={classes.topContentContainer}>
<Box>
<img src={activeEvent.imgUrl} alt="Event" />
</Box>
{activeEvent.type === "Webinar" ? (
<Box className={classes.topContentText} m="2.4rem">
<p>{activeEvent.startDate}</p>
<h2>{activeEvent.title}</h2>
<Typography variant="subtitle1">{activeEvent.location}</Typography>
<p>Start time: {activeEvent.startTime}</p>
</Box>
) : (
<Box className={classes.topContentText} m="2.4rem">
<p>
{activeEvent.startDate} - {activeEvent.endDate}
</p>
<h2>{activeEvent.title}</h2>
<Typography variant="subtitle1">{activeEvent.location}</Typography>
</Box>
)}
<Link
className={classes.donateBtn}
color="primary"
href="https://app.mobilecause.com/vf/ANGEL"
target="_blank"
rel="noopener"
>
DONATE NOW
</Link>
</Box>
<Box className={classes.detailsContainer}>
<Typography className={classes.details} variant="body1">
{activeEvent.details}
</Typography>
</Box>
{activeEvent.type === "Webinar" ? (
<Box className={classes.webinarBox}>
<p>Hosted by: {activeEvent.host}</p>
<p>Special Guest Speaker(s): {activeEvent.speakers}</p>
<a href={activeEvent.link} rel="noopener noreferrer" target="_blank">
Click Here to Join Us!
</a>
</Box>
) : null}
<>
{currentActivities.length >= 1 ? (
<Box className={classes.myActivitiesBox}>
<p>My Activities</p>
<table className={classes.table}>
<tbody>
<tr className={classes.headerRow}>
<th className={classes.tableH}>Name</th>
<th className={classes.tableH}>Date</th>
<th className={classes.tableH}>Location</th>
<th className={classes.tableH}>Time</th>
<th className={classes.tableH}>My Role</th>
</tr>
{currentActivities &&
currentActivities.map((activity, id) => (
<ActivityDetails key={id} activity={activity} />
))}
</tbody>
</table>
</Box>
) : null}
</>
<Box className={classes.sponsorBox}>
{activeEvent?.sponsors?.length > 0 ? (
<Typography variant="h3">Special thanks to our sponsors!</Typography>
) : null}
<ul>
{activeEvent.sponsors.length > 0
? activeEvent?.sponsors
?.split(", ")
.map(sponsor => <li>{sponsor}</li>)
: null}
</ul>
</Box>
</Box>
);
}
Example #13
Source File: MyEventCard.js From AdaptivApps-fe with MIT License | 4 votes |
export default function MyEventCard({ event, refetch }) {
const classes = useStyles();
const navigate = useNavigate();
// Retrieves current user info from Auth0
const { user } = useAuth0();
const { data } = useQuery(GET_PARTICIPANT_IDS, {
variables: { email: user.email, id: event.id },
fetchPolicy: "no-cache",
});
const [unregisterFromAll] = useMutation(UNREGISTER_FROM_ALL);
const [unregisterFromEventActivity] = useMutation(
UNREGISTER_FROM_EVENT_ACTIVITY
);
// Unregisters user from specified event and all it's activities
const unregisterFromEvent = async () => {
const participantIds = data?.participants?.map(participant => {
return participant.id;
});
const participantIdValue = data?.participants?.map(participant => {
return participant.id;
});
const participantId = JSON.stringify(participantIdValue).replace(
/[\[\]"]+/g,
""
);
data && data?.participants?.length === 1
? await unregisterFromEventActivity({
variables: {
id: event.id,
email: user.email,
participantId: participantId,
},
})
: data && data?.participants === null
? await unregisterFromEvent({
variables: {
id: event.id,
email: user.email,
},
})
: await unregisterFromAll({
variables: {
id: event.id,
email: user.email,
participantIds: participantIds,
},
});
await refetch();
};
const viewEventDetails = async () => {
await navigate(`/myevents/${event?.id}`);
};
return (
<Card className={classes.root}>
<CardActionArea className={classes.card}>
<Box>
<div className={classes.banner}>{event.type}</div>
<CardMedia
className={classes.cardImg}
component="img"
alt="Event"
width="15rem"
image={event?.imgUrl}
title="Angel City Event"
/>
</Box>
<CardContent className={classes.content}>
<Typography
className={classes.cardDate}
variant="body2"
color="textSecondary"
component="p"
>
{event.startDate} - {event.endDate}
</Typography>
<Typography
className={classes.cardTitle}
gutterBottom
variant="h5"
component="h2"
>
{event.title}
</Typography>
<Typography
className={classes.cardLoc}
variant="body2"
color="textSecondary"
component="p"
>
{event.location}
</Typography>
</CardContent>
</CardActionArea>
<CardActions className={classes.btnContainer}>
<Button onClick={viewEventDetails} className={classes.btn}>
View Details
</Button>
<Button className={classes.btn} onClick={unregisterFromEvent}>
Unregister
</Button>
</CardActions>
</Card>
);
}
Example #14
Source File: ProfileForm.js From AdaptivApps-fe with MIT License | 4 votes |
ProfileForm = ({ loading, profile, user, updateProfile }) => {
const [updated, setUpdated] = useState(false);
const [userProfile, setUserProfile] = useState(null);
const classes = useStyles();
const { refetch: refetchProfile } = useQuery(GET_USER_PROFILE, { variables: { email: user.email } });
const { handleSubmit, register, setValue, control } = useForm({
mode: "onSubmit",
validationSchema: ProfileSchema,
defaultValues: {
email: user && user.email,
firstName: userProfile && userProfile.firstName,
lastName: userProfile && userProfile.lastName,
displayName: userProfile && userProfile.displayName,
birthday: userProfile && userProfile.birthday,
bio: userProfile && userProfile.bio,
disability: userProfile && userProfile.disability,
},
});
// updates profile in the backend and frontend
const onSubmit = (formValues, e) => {
e.preventDefault();
// backend update
updateProfile({
variables: {
email: user.email,
firstName:
formValues.firstName === ""
? userProfile.firstName
: formValues.firstName,
lastName:
formValues.lastName === ""
? userProfile.lastName
: formValues.lastName,
displayName:
formValues.displayName === ""
? userProfile.displayName
: formValues.displayName,
birthday:
formValues.birthday === ""
? userProfile.birthday
: formValues.birthday,
bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
disability:
formValues.disability === ""
? userProfile.disability
: formValues.disability,
legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
},
});
// frontend update
setUserProfile({
email: user.email,
firstName:
formValues.firstName === ""
? userProfile.firstName
: formValues.firstName,
lastName:
formValues.lastName === "" ? userProfile.lastName : formValues.lastName,
displayName:
formValues.displayName === ""
? userProfile.displayName
: formValues.displayName,
birthday:
formValues.birthday === "" ? userProfile.birthday : formValues.birthday,
bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
disability:
formValues.disability === ""
? userProfile.disability
: formValues.disability,
legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
});
refetchProfile();
};
// updates form fields with new values
useEffect(() => {
if (!loading && !userProfile) setUserProfile(profile);
if (!loading && userProfile) {
setValue([
{ firstName: userProfile && userProfile.firstName },
{ lastName: userProfile && userProfile.lastName },
{ displayName: userProfile && userProfile.displayName },
{ birthday: userProfile && userProfile.birthday },
{ bio: userProfile && userProfile.bio },
{ disability: userProfile && userProfile.disability },
{ legal: userProfile && userProfile.legal },
]);
}
}, [loading, userProfile, setValue, profile]);
// alerts user to successful update, handy for screen readers
const handleUpdated = () => {
refetchProfile();
alert("Profile updated successfully!");
setUpdated(false);
};
const userPicture = user && user.picture;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography variant="h1" gutterBottom>
Account Information
</Typography>
</Box>
<Container className={classes.profileContainer}>
<Box className={classes.profileInfo}>
<img className={classes.profileImg} src={userPicture} alt="Profile" />
<Box className={classes.profileText}>
<Typography>
{userProfile && userProfile.firstName !== null
? `${userProfile && userProfile.firstName} ${userProfile &&
userProfile.lastName}`
: user && user.name}{" "}
</Typography>
<Typography>{user && user.email}</Typography>
</Box>
</Box>
<Typography className={classes.personalInfo} variant="h2" gutterBottom>
Personal Information
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)}>
<Box component="div" className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="firstName">
First Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="firstName"
variant="outlined"
type="text"
placeholder={userProfile ? userProfile.firstName : ""}
name="firstName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="lastName">
Last Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="lastName"
type="text"
variant="outlined"
placeholder={userProfile ? userProfile.lastName : ""}
name="lastName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="displayName">
Display Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="displayName"
type="text"
variant="outlined"
placeholder={userProfile ? userProfile.displayName : ""}
name="displayName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="birthday">
Date of Birth
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="birthday"
type="text"
variant="outlined"
name="birthday"
placeholder={userProfile ? userProfile.birthday : "mm/dd/yyyy"}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="bio">
Bio
</InputLabel>
<Controller
as={<TextField />}
className={classes.bio}
id="bio"
name="bio"
variant="outlined"
multiline={true}
rows="8"
placeholder={userProfile ? userProfile.bio : null}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="disability">
Disability Status
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="disability"
type="select"
variant="outlined"
name="disability"
ref={register}
placeholder={userProfile ? userProfile.disability : null}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="legal">
Are you over 18 years old?
</InputLabel>
<Controller
as={
<Select value={userProfile?.legal}>
<MenuItem value="">
{userProfile ? userProfile.legal : ""}
</MenuItem>
<MenuItem value={`Adult`}>Yes</MenuItem>
<MenuItem value={`Minor`}>No</MenuItem>
</Select>
}
className={classes.input}
id="legal"
name="legal"
variant="outlined"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Button
className={classes.button}
variant="outlined"
color="primary"
type="submit"
aria-label="save changes to user profile"
onClick={() => {
setUpdated(true);
}}
>
Save
</Button>
{updated === true ? handleUpdated() : null}
</Box>
</form>
</Container>
</main>
);
}
Example #15
Source File: index.js From AdaptivApps-fe with MIT License | 4 votes |
function SideNav(props) {
const { user } = props;
const { logout } = useAuth0();
const { container } = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
// Setup Chat and Announcement Subscriptions
const { refetch } = useQuery(GET_CHAT_ROOMS, { variables: { email: user.email } });
const { subscribeToMore: announcementSubscription, refetch: refetchAnnouncements } = useQuery(GET_ANNOUNCEMENTS, { variables: { isAnnouncementRoom: true } });
const { subscribeToMore } = useQuery(GET_MESSAGES, { variables: { email: user.email } });
const { data, refetch: refetchProfile } = useQuery(GET_USER_PROFILE, { variables: { email: user.email } });
const { subscribeToMore: notificationSubscription } = useQuery(GET_NOTIFICATIONS, { variables: { email: user.email } });
// Chat Subscription
const _subscribeToNewChats = subscribeToMore => {
subscribeToMore({
document: CHAT_SUBSCRIPTION,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev
const chat = subscriptionData.data.chat
refetch();
refetchProfile();
return Object.assign({}, prev, {
profile: {
chats: [chat, ...prev.profile.chats],
__typename: prev.profile.__typename
}
})
}
})
};
// Announcement Subscription
const _subscribeToNewAnnouncements = announcementSubscription => {
announcementSubscription({
document: ANNOUNCEMENT_SUBSCRIPTION,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev
const announcement = subscriptionData.data.announcement
refetchAnnouncements();
refetchProfile();
return Object.assign({}, prev, {
announcements: [announcement, ...prev.announcements],
__typename: prev.__typename
})
}
})
};
_subscribeToNewAnnouncements(announcementSubscription);
// Notification Subscription
const _subscribeToNewNotifications = notificationSubscription => {
notificationSubscription({
document: NOTIFICATION_SUBSCRIPTION,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev
const notification = subscriptionData.data.notification
refetch();
refetchAnnouncements();
refetchProfile();
return Object.assign({}, prev, {
profile: {
notifications: [notification, ...prev.profile.notifications],
__typename: prev.profile.__typename
}
})
}
})
};
_subscribeToNewNotifications(notificationSubscription);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const drawer = (
<>
<Box className={classes.imgBox}>
<img src={acsLogo} alt="ACS Logo" />
</Box>
<Box className={classes.navContainer}>
<NavLink to="calendar" className={classes.navLink}>
<CalendarTodayIcon className={classes.navIcon} />
<p>Events Calendar</p>
</NavLink>
<NavLink to="myevents" className={classes.navLink}>
<BookmarkIcon className={classes.navIcon} />
<p>My Events</p>
</NavLink>
<NavLink to="/" className={classes.navLink}>
<UserIcon className={classes.navIcon} />
<p>My Profile</p>
</NavLink>
{data === undefined || data.profile === null || (data && (data?.profile.firstName === null || data?.profile.lastName === null)) ?
(
<Tooltip title="Please complete your profile information to access Chats">
<div className={classes.disabledNavLink}>
{(data && data.profile !== null) && (data && data?.profile.notifications.length > 0) ? (
<StyledBadge
overlap='circle'
badgeContent={data.profile.notifications.length}>
<ForumOutlinedIcon className={classes.navIcon} />
</StyledBadge>
) : (
<ForumOutlinedIcon className={classes.navIcon} />
)}
<p>Chats</p>
</div>
</Tooltip>
)
:
(
<NavLink to="/chats" className={classes.navLink}>
{data && data?.profile.notifications.length > 0 ? (
<StyledBadge
overlap='circle'
badgeContent={data.profile.notifications.length}
>
<ForumOutlinedIcon className={classes.navIcon} />
</StyledBadge>
) : (
<ForumOutlinedIcon className={classes.navIcon} />
)}
<p>Chats</p>
</NavLink>
)}
{user && user[config.roleUrl].includes("Admin") ? (
<>
<NavLink to="manage" className={classes.navLink}>
<HomeIcon className={classes.navIcon} />
<p>Manage Events</p>
</NavLink>
<NavLink to="users" className={classes.navLink}>
<GroupIcon className={classes.navIcon} />
<p>Manage Users</p>
</NavLink>
</>
) : null}
</Box>
<Box className={classes.logoutContainer}>
<Button className={classes.logoutBtn} onClick={() => logout()}>
<IconContext.Provider
value={{ style: { transform: "rotate(180deg)" } }}
>
<FiLogOut className={classes.logoutIcon} />
<p className={classes.logoutP}>Log Out</p>
</IconContext.Provider>
</Button>
</Box>
</>
);
return (
<div className={classes.root}>
<Toolbar position="fixed">
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon className={classes.navIcon} />
</IconButton>
</Toolbar>
<nav className={classes.drawer} aria-label="mailbox folders">
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer
container={container}
variant="temporary"
anchor={theme.direction === "rtl" ? "right" : "left"}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
</div>
);
}