Skip to content

Commit

Permalink
feat(frontend): 🎸 show loader after remembered sheet click'
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Clark committed Jun 23, 2023
1 parent 8425d30 commit 9bc6280
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 7 deletions.
73 changes: 73 additions & 0 deletions src/lib/global-loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
Modal,
ModalContent,
ModalOverlay,
Spinner,
Text,
} from "@chakra-ui/react";
import { atom, useAtomValue, useSetAtom } from "jotai";
import { FC, useEffect } from "react";

const isGlobalLoadingAtom = atom(false);
const globalLoadingMessageAtom = atom<string | undefined>(undefined);

/**
* To use this, just call `useGlobalLoading` in your component,
* passing in a boolean for whether or not the global loader should
* be shown and an optional message to display.
*/
export const useGlobalLoading = (isLoading: boolean, message?: string) => {
const setIsLoading = useSetAtom(isGlobalLoadingAtom);
const setMessage = useSetAtom(globalLoadingMessageAtom);

useEffect(() => {
setIsLoading(isLoading);
setMessage(message);
}, [isLoading, message, setIsLoading, setMessage]);

useEffect(() => {
return () => {
setIsLoading(false);
setMessage(undefined);
};
}, [setIsLoading, setMessage]);
};

/**
* Place this in your `_app.tsx` file
*/
export const GlobalLoader: FC = () => {
const isLoading = useAtomValue(isGlobalLoadingAtom);
const message = useAtomValue(globalLoadingMessageAtom);

return (
<Modal
isOpen={isLoading}
onClose={() => {}}
closeOnOverlayClick={false}
isCentered
autoFocus={false}
>
<ModalOverlay />
<ModalContent
bg="transparent"
border="none"
display="flex"
flexDirection="column"
alignItems="center"
>
<Spinner
size="xl"
emptyColor="gray.200"
color="primary.500"
thickness="4px"
/>
{message && (
<Text fontWeight="bold" mt="group">
{message}
</Text>
)}
</ModalContent>
</Modal>
);
};
5 changes: 4 additions & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChakraProvider, ColorModeScript } from "@chakra-ui/react";
import React from "react";
import { IN_DEV, IN_PREVIEW, theme } from "$root/config";
import { IN_DEV, IN_PREVIEW } from "$root/config";
import Head from "next/head";
import { appName } from "$root/constants";
import { Meta } from "$root/components";
Expand All @@ -17,6 +17,8 @@ import queries from "$root/hooks/queries";

import { Analytics } from "@vercel/analytics/react";
import { match } from "ts-pattern";
import { GlobalLoader } from "$global-loader";
import theme from "$root/theme/theme";

/**
* Generate a selector to add a background color
Expand Down Expand Up @@ -86,6 +88,7 @@ const MyApp = ({ Component, pageProps }: AppProps): React.ReactElement => {
`}
/>
<Component {...pageProps} />
<GlobalLoader />
<Analytics
debug={IN_DEV || IN_PREVIEW}
beforeSend={({ url, ...event }) => {
Expand Down
24 changes: 19 additions & 5 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Center, Container, Divider, Flex } from "@chakra-ui/react";
import { Button, Center, Container, Divider, Flex } from "@chakra-ui/react";
import { testIdGeneratorFactory } from "$tests/utils/testUtils";
import {
infoPageUrl,
Expand All @@ -16,11 +16,14 @@ import {
GetStartedButton,
} from "$root/components";
import { getSheetLink } from "$root/utils";
import { FC } from "react";
import { FC, useEffect } from "react";
import useRenderLogging from "$root/hooks/useRenderLogging";
import { useRememberedSheets } from "$sheets/store";
import { useNextHydrationMatchWorkaround } from "$root/hooks";
import { MAINTENANCE_MODE } from "$root/config";
import { useRouter } from "next/router";
import { useMutation } from "@tanstack/react-query";
import { useGlobalLoading } from "$global-loader";

const getTestId = testIdGeneratorFactory("Home");

Expand All @@ -43,6 +46,15 @@ const Home: FC = () => {
[]
);

const { push, prefetch } = useRouter();
const routerPushMutation = useMutation(push);
useGlobalLoading(routerPushMutation.isLoading, "Loading sheet...");

useEffect(() => {
// We prefetch the remembered sheets manually
rememberedSheets.forEach((sheet) => prefetch(getSheetLink(sheet.id)));
}, [rememberedSheets, prefetch]);

return (
<View url={appDomain}>
<Center w="100vw" h="full">
Expand Down Expand Up @@ -85,8 +97,10 @@ const Home: FC = () => {
</H3>
<Center flexWrap="wrap" w={[400, 400, 600]} gap="group">
{rememberedSheets.map((sheet) => (
<ButtonLink
href={getSheetLink(sheet.id)}
<Button
onClick={() =>
routerPushMutation.mutate(getSheetLink(sheet.id))
}
variant="outline"
key={sheet.id}
w={64}
Expand All @@ -95,7 +109,7 @@ const Home: FC = () => {
size="sm"
>
{sheet.name}
</ButtonLink>
</Button>
))}
</Center>
</>
Expand Down
20 changes: 19 additions & 1 deletion src/theme/semanticTokens.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
const semanticTokens = {
import { DeepPartial } from "@chakra-ui/react";

/**
* Add to this as needed.
*/
type SemanticTokensListing = DeepPartial<{
colors: Record<
string,
Record<
string,
{
default: string;
_dark: string;
}
>
>;
}>;

const semanticTokens: SemanticTokensListing = {
colors: {
shade: {
"50": {
Expand Down

0 comments on commit 9bc6280

Please sign in to comment.