Skip to content

Commit

Permalink
feat: add report a bug button using sentry and add a fallback page us…
Browse files Browse the repository at this point in the history
…ing error boundaries (#800)


Co-authored-by: spaenleh <[email protected]>
  • Loading branch information
LinaYahya and spaenleh authored Oct 16, 2023
1 parent b496d59 commit 785beba
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 46 deletions.
44 changes: 26 additions & 18 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Route, Routes } from 'react-router-dom';
import { saveUrlForRedirection } from '@graasp/sdk';
import { CustomInitialLoader, withAuthorization } from '@graasp/ui';

import * as Sentry from '@sentry/react';

import { DOMAIN } from '@/config/env';
import { SIGN_IN_PATH } from '@/config/externalPaths';

Expand All @@ -19,6 +21,7 @@ import {
buildItemPath,
} from '../config/paths';
import { hooks } from '../config/queryClient';
import FallbackComponent from './Fallback';
import RecycleBinScreen from './RecycleBinScreen';
import SharedItems from './SharedItems';
import { useCurrentUserContext } from './context/CurrentUserContext';
Expand Down Expand Up @@ -73,24 +76,29 @@ const App = (): JSX.Element => {
);

return (
<Routes>
<Route path={HOME_PATH} element={<HomeWithAuthorization />} />
<Route path={SHARED_ITEMS_PATH} element={<SharedWithAuthorization />} />
<Route
path={FAVORITE_ITEMS_PATH}
element={<FavoriteWithAuthorization />}
/>
<Route
path={PUBLISHED_ITEMS_PATH}
element={<PublishedWithAuthorization />}
/>
<Route path={buildItemPath()} element={<ItemScreen />} />
<Route path={MEMBER_PROFILE_PATH} element={<MemberWithAuthorization />} />
<Route path={RECYCLE_BIN_PATH} element={<RecycleWithAuthorization />} />
<Route path={ITEMS_PATH} element={<HomeWithAuthorization />} />
<Route path={REDIRECT_PATH} element={<Redirect />} />
<Route element={<Redirect />} />
</Routes>
<Sentry.ErrorBoundary fallback={<FallbackComponent />}>
<Routes>
<Route path={HOME_PATH} element={<HomeWithAuthorization />} />
<Route path={SHARED_ITEMS_PATH} element={<SharedWithAuthorization />} />
<Route
path={FAVORITE_ITEMS_PATH}
element={<FavoriteWithAuthorization />}
/>
<Route
path={PUBLISHED_ITEMS_PATH}
element={<PublishedWithAuthorization />}
/>
<Route path={buildItemPath()} element={<ItemScreen />} />
<Route
path={MEMBER_PROFILE_PATH}
element={<MemberWithAuthorization />}
/>
<Route path={RECYCLE_BIN_PATH} element={<RecycleWithAuthorization />} />
<Route path={ITEMS_PATH} element={<HomeWithAuthorization />} />
<Route path={REDIRECT_PATH} element={<Redirect />} />
<Route element={<Redirect />} />
</Routes>
</Sentry.ErrorBoundary>
);
};

Expand Down
52 changes: 52 additions & 0 deletions src/components/Fallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useNavigate } from 'react-router';

import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
import { Box, Button, Stack, Typography } from '@mui/material';

import { useBuilderTranslation } from '@/config/i18n';
import { HOME_PATH } from '@/config/paths';

import { BUILDER } from '../langs/constants';

const FallbackComponent = (): JSX.Element => {
const navigate = useNavigate();
const { t: translateBuilder } = useBuilderTranslation();

return (
<Stack
direction={['column-reverse', 'row']}
justifyContent="center"
alignItems="center"
height="100svh"
spacing={4}
>
<Box>
<Typography variant="h1">
{translateBuilder(BUILDER.FALLBACK_TITLE)}
</Typography>
<Typography>{translateBuilder(BUILDER.FALLBACK_TEXT)}</Typography>
<Button
sx={{ mt: 3 }}
variant="contained"
onClick={() => navigate(HOME_PATH)}
>
{translateBuilder(BUILDER.FALLBACK_BACK_TO_HOME)}
</Button>
</Box>
<ErrorOutlineIcon
fontSize="large"
htmlColor="#5050d2"
sx={{
display: 'flex',
width: '100%',
maxWidth: '10em',
aspectRatio: 1,
height: 'auto',
maxHeight: '10em',
}}
/>
</Stack>
);
};

export default FallbackComponent;
2 changes: 1 addition & 1 deletion src/components/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const Root = (): JSX.Element => (
</Router>
</ThemeProvider>
</I18nextProvider>
{import.meta.env.DEV && <ReactQueryDevtools />}
{import.meta.env.DEV && <ReactQueryDevtools position="bottom-right" />}
</QueryClientProvider>
);

Expand Down
81 changes: 54 additions & 27 deletions src/components/main/MainMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { useLocation, useNavigate } from 'react-router';

import { BugReport } from '@mui/icons-material';
import AutoStoriesIcon from '@mui/icons-material/AutoStories';
import DeleteIcon from '@mui/icons-material/Delete';
import FolderIcon from '@mui/icons-material/Folder';
import FolderSharedIcon from '@mui/icons-material/FolderShared';
import Star from '@mui/icons-material/Star';
import { styled, useTheme } from '@mui/material';
import {
ListItem,
ListItemButton,
ListItemText,
Stack,
styled,
useTheme,
} from '@mui/material';
import ListItemIcon from '@mui/material/ListItemIcon';

import { DEFAULT_LANG } from '@graasp/sdk';
import { MainMenu as GraaspMainMenu, LibraryIcon, MenuItem } from '@graasp/ui';

import { captureMessage, showReportDialog } from '@sentry/react';

import { TUTORIALS_LINK } from '../../config/constants';
import { useBuilderTranslation } from '../../config/i18n';
import i18n, { useBuilderTranslation } from '../../config/i18n';
import {
FAVORITE_ITEMS_PATH,
HOME_PATH,
Expand All @@ -22,20 +33,6 @@ import {
import { BUILDER } from '../../langs/constants';
import { useCurrentUserContext } from '../context/CurrentUserContext';

const StyledLink = styled('a')(({ theme }) => ({
position: 'absolute',
bottom: 0,
width: '100%',
display: 'flex',
alignItems: 'center',
padding: theme.spacing(2),
boxSizing: 'border-box',
color: 'grey',
textDecoration: 'none',
'&:hover': {
color: theme.palette.primary.main,
},
}));
const StyledMenuItem = styled(MenuItem)(({ theme }) => ({
'&:hover': {
color: theme.palette.primary.main,
Expand All @@ -55,13 +52,38 @@ const MainMenu = (): JSX.Element => {
navigate(path);
};

const resourcesLink = (
<StyledLink href={TUTORIALS_LINK} target="_blank">
<ListItemIcon>
<AutoStoriesIcon />
</ListItemIcon>
{translateBuilder('Tutorials')}
</StyledLink>
const openBugReport = () => {
const eventId = captureMessage(
`Graasp Builder | User Feedback ${Date.now()}`,
);
// this will be reported in sentry user feedback issues
showReportDialog({
eventId,
title: translateBuilder(BUILDER.REPORT_A_BUG),
lang: i18n.language || DEFAULT_LANG,
});
};

const reportBugLink = (
<ListItem disablePadding>
<ListItemButton onClick={openBugReport}>
<ListItemIcon>
<BugReport />
</ListItemIcon>
<ListItemText>{translateBuilder(BUILDER.REPORT_A_BUG)}</ListItemText>
</ListItemButton>
</ListItem>
);

const resourceLinks = (
<ListItem disablePadding>
<ListItemButton href={TUTORIALS_LINK} target="_blank">
<ListItemIcon>
<AutoStoriesIcon />
</ListItemIcon>
<ListItemText>{translateBuilder('Tutorials')}</ListItemText>
</ListItemButton>
</ListItem>
);

const renderAuthenticatedMemberMenuItems = () => {
Expand All @@ -76,7 +98,7 @@ const MainMenu = (): JSX.Element => {
}

return (
<>
<div>
<MenuItem
onClick={() => goTo(HOME_PATH)}
selected={pathname === HOME_PATH}
Expand Down Expand Up @@ -113,14 +135,19 @@ const MainMenu = (): JSX.Element => {
text={translateBuilder(BUILDER.RECYCLE_BIN_TITLE)}
icon={<DeleteIcon />}
/>
</>
</div>
);
};

return (
<GraaspMainMenu fullHeight>
{renderAuthenticatedMemberMenuItems()}
{resourcesLink}
<Stack direction="column" height="100%" justifyContent="space-between">
{renderAuthenticatedMemberMenuItems()}
<div>
{reportBugLink}
{resourceLinks}
</div>
</Stack>
</GraaspMainMenu>
);
};
Expand Down
4 changes: 4 additions & 0 deletions src/langs/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@
"USER_SWITCH_SIGN_OUT_BUTTON": "خروج",
"USER_SWITCH_SIGNED_OUT_TOOLTIP": "أنت غير مسجل الدخول.",
"USER_SWITCH_SWITCH_USER_TEXT": "تسجيل الدخول بحساب آخر",
"FALLBACK_TITLE": "عفواً",
"FALLBACK_TEXT": "حدث خطأ غير متوقع، يرحى المحاولة لاحقاً",
"FALLBACK_BACK_TO_HOME": "الرجوع إلى الصفحة الرئيسية",
"REPORT_A_BUG": "الإبلاغ عن مشكلة",
"DELETE_MEMBERSHIP": "حذف العضوية",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "تأكيد",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "هل أنت متأكد من إلغاء عضويتك على هذا العنصر؟",
Expand Down
4 changes: 4 additions & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ export const BUILDER = {
STATUS_TOOLTIP_IS_COLLAPSIBLE: 'STATUS_TOOLTIP_IS_COLLAPSIBLE',
STATUS_TOOLTIP_SHOW_CHATBOX: 'STATUS_TOOLTIP_SHOW_CHATBOX',
SETTINGS_FILE_SETTINGS_TITLE: 'SETTINGS_FILE_SETTINGS_TITLE',
FALLBACK_TITLE: 'FALLBACK_TITLE',
FALLBACK_TEXT: 'FALLBACK_TEXT',
FALLBACK_BACK_TO_HOME: 'FALLBACK_BACK_TO_HOME',
REPORT_A_BUG: 'REPORT_A_BUG',
DELETE_MEMBERSHIP: 'DELETE_MEMBERSHIP',
DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON:
'DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON',
Expand Down
4 changes: 4 additions & 0 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@
"STATUS_TOOLTIP_IS_COLLAPSIBLE": "Collapsible",
"STATUS_TOOLTIP_SHOW_CHATBOX": "Chatbox visible",
"SETTINGS_FILE_SETTINGS_TITLE": "File Settings",
"FALLBACK_TITLE": "Oops!",
"FALLBACK_TEXT": "Sorry, something went wrong. Try again later.",
"FALLBACK_BACK_TO_HOME": "Back to homepage",
"REPORT_A_BUG": "Report a Bug",
"DELETE_MEMBERSHIP": "Delete Membership",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "Confirm",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "Are you sure you want to delete your own permission on this item? You will loose access to this item, this action can not be undone.",
Expand Down
4 changes: 4 additions & 0 deletions src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@
"STATUS_TOOLTIP_IS_COLLAPSIBLE": "Minifié",
"STATUS_TOOLTIP_SHOW_CHATBOX": "Chatbox visible",
"SETTINGS_FILE_SETTINGS_TITLE": "Paramètres du fichier",
"FALLBACK_TITLE": "Oops!",
"FALLBACK_TEXT": "Désolé, une erreur inattendue est survenue. Veuillez réessayer plus tard.",
"FALLBACK_BACK_TO_HOME": "Retour à la page d'accueil",
"REPORT_A_BUG": "Signaler un problème",
"DELETE_MEMBERSHIP": "Supprimer l'autorisation",
"DELETE_MEMBERSHIP_MODAL_CONFIRM_BUTTON": "Confirmer",
"DELETE_OWN_MEMBERSHIP_MESSAGE": "Êtes-vous sûr de vouloir supprimer votre propre autorisation sur cet élément ? Vous perdrez l'accès à cet élément, cette action est irréversible.",
Expand Down

0 comments on commit 785beba

Please sign in to comment.