slice-machine-ui 1.19.2-dev-in-app-guide.2 → 1.19.2-dev-in-app-guide.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/pages/_app.tsx CHANGED
@@ -34,7 +34,7 @@ import { PersistGate } from "redux-persist/integration/react";
34
34
  import { ThemeProvider as ThemeUIThemeProvider, useThemeUI } from "theme-ui";
35
35
 
36
36
  import { AppLayout, AppLayoutContent } from "@components/AppLayout";
37
- import { InAppGuideDialog } from "@src/features/inAppGuide/InAppGuideDialog";
37
+ import { InAppGuideProvider } from "@src/features/inAppGuide/InAppGuideContext";
38
38
 
39
39
  import SliceMachineApp from "../components/App";
40
40
  import LoadingPage from "../components/LoadingPage";
@@ -123,48 +123,52 @@ function MyApp({
123
123
  <ThemeUIThemeProvider theme={theme}>
124
124
  <RemoveDarkMode>
125
125
  <ThemeProvider mode="light">
126
- <ErrorBoundary
127
- renderError={(error) => {
128
- console.error(error);
129
-
130
- return (
131
- <AppLayout>
132
- <AppLayoutContent>
133
- <Box alignItems="center" justifyContent="center">
134
- <DefaultErrorMessage
135
- title="Error"
136
- description="An error occurred while rendering the app."
137
- />
138
- </Box>
139
- </AppLayoutContent>
140
- </AppLayout>
141
- );
142
- }}
143
- >
144
- <TooltipProvider>
145
- {!smStore || !serverState ? (
146
- <LoadingPage />
147
- ) : (
148
- <Provider store={smStore.store}>
149
- <ConnectedRouter Router={Router}>
150
- <PersistGate loading={null} persistor={smStore.persistor}>
151
- <RouteChangeProvider>
152
- <Suspense fallback={<LoadingPage />}>
153
- <ComponentLayout>
154
- <Component {...pageProps} />
155
- </ComponentLayout>
156
- </Suspense>
157
- </RouteChangeProvider>
126
+ <TooltipProvider>
127
+ {!smStore || !serverState ? (
128
+ <LoadingPage />
129
+ ) : (
130
+ <Provider store={smStore.store}>
131
+ <ConnectedRouter Router={Router}>
132
+ <PersistGate loading={null} persistor={smStore.persistor}>
133
+ <ErrorBoundary
134
+ renderError={(error) => {
135
+ console.error(error);
136
+
137
+ return (
138
+ <AppLayout>
139
+ <AppLayoutContent>
140
+ <Box
141
+ alignItems="center"
142
+ justifyContent="center"
143
+ >
144
+ <DefaultErrorMessage
145
+ title="Error"
146
+ description="An error occurred while rendering the app."
147
+ />
148
+ </Box>
149
+ </AppLayoutContent>
150
+ </AppLayout>
151
+ );
152
+ }}
153
+ >
158
154
  <Suspense>
159
- <InAppGuideDialog />
155
+ <InAppGuideProvider>
156
+ <RouteChangeProvider>
157
+ <Suspense fallback={<LoadingPage />}>
158
+ <ComponentLayout>
159
+ <Component {...pageProps} />
160
+ </ComponentLayout>
161
+ </Suspense>
162
+ </RouteChangeProvider>
163
+ </InAppGuideProvider>
160
164
  </Suspense>
161
- </PersistGate>
162
- </ConnectedRouter>
163
- <ToastContainer />
164
- </Provider>
165
- )}
166
- </TooltipProvider>
167
- </ErrorBoundary>
165
+ </ErrorBoundary>
166
+ </PersistGate>
167
+ </ConnectedRouter>
168
+ <ToastContainer />
169
+ </Provider>
170
+ )}
171
+ </TooltipProvider>
168
172
  </ThemeProvider>
169
173
  </RemoveDarkMode>
170
174
  </ThemeUIThemeProvider>
@@ -0,0 +1,49 @@
1
+ import {
2
+ Dispatch,
3
+ FC,
4
+ PropsWithChildren,
5
+ SetStateAction,
6
+ createContext,
7
+ useContext,
8
+ } from "react";
9
+
10
+ import { usePersistedState } from "@src/hooks/usePersistedState";
11
+
12
+ import { InAppGuideDialog } from "./InAppGuideDialog";
13
+
14
+ type InAppGuideContextValue = {
15
+ isInAppGuideOpen: boolean;
16
+ setIsInAppGuideOpen: Dispatch<SetStateAction<boolean>>;
17
+ };
18
+
19
+ export const InAppGuideContext = createContext<
20
+ InAppGuideContextValue | undefined
21
+ >(undefined);
22
+
23
+ export const InAppGuideProvider: FC<PropsWithChildren> = (props) => {
24
+ const { children } = props;
25
+ const [isInAppGuideOpen, setIsInAppGuideOpen] = usePersistedState(
26
+ true,
27
+ "isInAppGuideOpen",
28
+ );
29
+
30
+ return (
31
+ <InAppGuideContext.Provider
32
+ value={{
33
+ isInAppGuideOpen,
34
+ setIsInAppGuideOpen,
35
+ }}
36
+ >
37
+ {children}
38
+ <InAppGuideDialog />
39
+ </InAppGuideContext.Provider>
40
+ );
41
+ };
42
+
43
+ export const useInAppGuide = () => {
44
+ const context = useContext(InAppGuideContext);
45
+ if (context === undefined) {
46
+ throw new Error("useInAppGuide must be used within a InAppGuideProvider");
47
+ }
48
+ return context;
49
+ };
@@ -14,21 +14,20 @@ import {
14
14
  import { Counter } from "@src/components/Counter";
15
15
  import { FlowerBackgroundIcon } from "@src/icons/FlowerBackgroundIcon";
16
16
  import { HelpIcon } from "@src/icons/HelpIcon";
17
- import { usePersistedState } from "@src/hooks/usePersistedState";
18
17
  import { useIsEmptyProject } from "@src/hooks/useIsEmptyProject";
18
+ import { useRepositoryInformation } from "@src/hooks/useRepositoryInformation";
19
19
 
20
20
  import { IN_APP_GUIDE_CONTENT } from "./inAppGuideContent";
21
+ import { useInAppGuide } from "./InAppGuideContext";
21
22
 
22
23
  export const InAppGuideDialog: FC = () => {
23
24
  const isEmptyProject = useIsEmptyProject();
24
- const [isInAppGuideOpen, setIsInAppGuideOpen] = usePersistedState(
25
- true,
26
- "isInAppGuideOpen",
27
- );
25
+ const { isInAppGuideOpen, setIsInAppGuideOpen } = useInAppGuide();
26
+ const { repositoryUrl } = useRepositoryInformation();
28
27
 
29
- // TODO: Use IconButton from @prismicio/editor-ui
28
+ // TODO: Use new IconButton component from editor-ui
30
29
  const trigger =
31
- isInAppGuideOpen === false && isEmptyProject === false ? (
30
+ isEmptyProject === false ? (
32
31
  <Box position="fixed" right={16} bottom={16}>
33
32
  <button
34
33
  style={{
@@ -87,7 +86,11 @@ export const InAppGuideDialog: FC = () => {
87
86
  controls
88
87
  loop
89
88
  />
90
- <Text>{content.description}</Text>
89
+ <Text>
90
+ {typeof content.description === "function"
91
+ ? content.description(repositoryUrl)
92
+ : content.description}
93
+ </Text>
91
94
  </Box>
92
95
 
93
96
  <Separator />
@@ -6,32 +6,32 @@ export const IN_APP_GUIDE_CONTENT = {
6
6
  {
7
7
  title: "Add slice to your page",
8
8
  videoUrl:
9
- "https://images.prismic.io/page-builder-assets/8f5df837-d8c2-4aed-832c-dec21d3915d0_New+Recording+Jul+18+2023+0350+PM.mp4",
9
+ "https://res.cloudinary.com/dmtf1daqp/video/upload/v1700213517/IN-APP-GUIDE-SM/ADD_SLICE.mp4",
10
10
  description:
11
11
  "Try one of our templates to get started after the creation of your first page",
12
12
  },
13
13
  {
14
14
  title: "Code your page",
15
15
  videoUrl:
16
- "https://images.prismic.io/page-builder-assets/8f5df837-d8c2-4aed-832c-dec21d3915d0_New+Recording+Jul+18+2023+0350+PM.mp4",
16
+ "https://res.cloudinary.com/dmtf1daqp/video/upload/v1700213517/IN-APP-GUIDE-SM/CODE_SNIP.mp4",
17
17
  description:
18
18
  "Slice Machine provides code snippets. Copy-paste them into your page component to render your page.",
19
19
  },
20
20
  {
21
21
  title: "Push models to the Page Builder",
22
22
  videoUrl:
23
- "https://images.prismic.io/page-builder-assets/8f5df837-d8c2-4aed-832c-dec21d3915d0_New+Recording+Jul+18+2023+0350+PM.mp4",
23
+ "https://res.cloudinary.com/dmtf1daqp/video/upload/v1700213517/IN-APP-GUIDE-SM/PUSH.mp4",
24
24
  description:
25
- "You have just created some models, but you can’t use them yet. First, you must push them to the Page Builder. The Page Builder is where you create content. Go head — push your models.",
25
+ "You have just created some models, but you can't use them yet. First, you must push them to the Page Builder. The Page Builder is where you create content. Go head — push your models.",
26
26
  },
27
27
  {
28
28
  title: "Create your first page",
29
29
  videoUrl:
30
- "https://images.prismic.io/page-builder-assets/8f5df837-d8c2-4aed-832c-dec21d3915d0_New+Recording+Jul+18+2023+0350+PM.mp4",
31
- description: (
30
+ "https://res.cloudinary.com/dmtf1daqp/video/upload/v1700213517/IN-APP-GUIDE-SM/WRITE.mp4",
31
+ description: (repositoryUrl: string) => (
32
32
  <>
33
33
  In your{" "}
34
- <TextLink href="TODO" underline>
34
+ <TextLink href={repositoryUrl} underline>
35
35
  Page Builder
36
36
  </TextLink>
37
37
  , create your first page. Add slices to the page to create content.
@@ -42,16 +42,8 @@ export const IN_APP_GUIDE_CONTENT = {
42
42
  {
43
43
  title: "Render your page",
44
44
  videoUrl:
45
- "https://images.prismic.io/page-builder-assets/8f5df837-d8c2-4aed-832c-dec21d3915d0_New+Recording+Jul+18+2023+0350+PM.mp4",
46
- description: (
47
- <>
48
- Run your project on{" "}
49
- <TextLink href="TODO" underline>
50
- localhost
51
- </TextLink>{" "}
52
- to see your first page.
53
- </>
54
- ),
45
+ "https://res.cloudinary.com/dmtf1daqp/video/upload/v1700213517/IN-APP-GUIDE-SM/PREVIEW.mp4",
46
+ description: "Run your project on localhost to see your first page.",
55
47
  },
56
48
  ],
57
49
  successTitle: "You have made your first page!",
@@ -0,0 +1,24 @@
1
+ import { useSelector } from "react-redux";
2
+
3
+ import { SliceMachineStoreType } from "@src/redux/type";
4
+ import { getApiEndpoint, getRepoName } from "@src/modules/environment";
5
+
6
+ // TODO: This hook should be extracted to a new manager endpoint
7
+ export function useRepositoryInformation() {
8
+ const { repositoryName, apiEndpoint } = useSelector(
9
+ (store: SliceMachineStoreType) => ({
10
+ repositoryName: getRepoName(store),
11
+ apiEndpoint: getApiEndpoint(store),
12
+ }),
13
+ );
14
+ const repositoryDomain = new URL(apiEndpoint).hostname.replace(".cdn", "");
15
+ const repositoryUrl = apiEndpoint
16
+ .replace(".cdn.", ".")
17
+ .replace("/api/v2", "");
18
+
19
+ return {
20
+ repositoryName,
21
+ repositoryDomain,
22
+ repositoryUrl,
23
+ };
24
+ }