Skip to content

Commit

Permalink
Add loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonF committed Oct 22, 2024
1 parent 39fdb74 commit 038720c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
6 changes: 6 additions & 0 deletions src/scenes/Root/Notifications/Notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Notification } from './Notification';
import { NotificationListDocument } from './NotificationList.graphql';
import { ReadNotificationDocument } from './ReadNotification.graphql';
import { NotificationFragment } from './Views';
import { BaseView } from './Views/Base';

export const Notifications = () => {
const enabled = useFeatureEnabled('notifications');
Expand Down Expand Up @@ -113,6 +114,11 @@ export const Notifications = () => {
<Divider sx={{ mx: 1 }} />
</Box>
<Stack divider={<Divider />} sx={{ p: 1, pt: 0.5, gap: 0.5 }}>
{loading && !data
? Array.from({ length: 5 }).map((_, i) => (
<BaseView key={i} notification="loading" />
))
: null}
{data?.items.map((notification) => (
<Notification
key={notification.id}
Expand Down
3 changes: 2 additions & 1 deletion src/scenes/Root/Notifications/ReadIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CheckCircleOutlined, Circle } from '@mui/icons-material';
import { IconButton, IconButtonProps, Tooltip } from '@mui/material';
import { Tooltip } from '@mui/material';
import { IconButton, IconButtonProps } from '~/components/IconButton';
import { NotificationProp } from './Views';

export const ReadIndicator = ({
Expand Down
39 changes: 30 additions & 9 deletions src/scenes/Root/Notifications/Views/Base.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Stack, Theme, Typography } from '@mui/material';
import { Box, Skeleton, Stack, Theme, Typography } from '@mui/material';
// eslint-disable-next-line @seedcompany/no-restricted-imports
import type { OverridableComponent } from '@mui/material/OverridableComponent';
import { alpha } from '@mui/material/styles';
Expand All @@ -19,23 +19,32 @@ interface NotificationTypeMap<
AdditionalProps = object,
RootComponent extends ElementType = typeof Box
> {
props: NotificationProp & ChildrenProp & StyleProps & AdditionalProps;
props: (NotificationProp | { notification: 'loading' }) &
ChildrenProp &
StyleProps &
AdditionalProps;
defaultComponent: RootComponent;
}

export const BaseView: OverridableComponent<NotificationTypeMap> = (
props: NotificationTypeMap['props'] & { component?: ElementType }
) => {
const { component: Root = Box, notification, children, ...rest } = props;
const { unread, createdAt } = notification;
const {
component: Root = Box,
notification: notificationIn,
children,
...rest
} = props;
const notification =
notificationIn !== 'loading' ? notificationIn : undefined;
return (
<Root
color="primary"
{...rest}
sx={[
(theme: Theme) => ({
width: 1,
backgroundColor: unread
backgroundColor: notification?.unread
? alpha(theme.palette.primary.light, 0.1)
: undefined,
borderRadius: 1,
Expand All @@ -48,13 +57,25 @@ export const BaseView: OverridableComponent<NotificationTypeMap> = (
]}
>
<Stack sx={{ flex: 1, gap: 1, alignItems: 'flex-start' }}>
{children}
{notification ? (
children
) : (
<Skeleton width={`${Math.random() * (100 - 25) + 25}%`} />
)}
<Typography variant="caption" color="textSecondary">
<RelativeDateTime date={createdAt} />
{notification ? (
<RelativeDateTime date={notification.createdAt} />
) : (
<Skeleton width="30%" />
)}
</Typography>
</Stack>
{/* Just to reserve layout */}
<ReadIndicator disabled sx={{ visibility: 'hidden' }} />
{notification ? (
// Just to reserve layout
<ReadIndicator disabled sx={{ visibility: 'hidden' }} />
) : (
<ReadIndicator loading css={{ transform: 'scale(.7)' }} />
)}
</Root>
);
};

0 comments on commit 038720c

Please sign in to comment.