Skip to content

Commit

Permalink
Merge pull request #250 from IntersectMBO/feature/usersnap-integration
Browse files Browse the repository at this point in the history
feature: Usersnap integration to Feedback button
  • Loading branch information
Kristina2103 authored Aug 6, 2024
2 parents ab0e525 + fcf2ff2 commit d4d6698
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 2 deletions.
6 changes: 6 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@mui/material": "^5.15.7",
"@mui/material-nextjs": "^5.15.11",
"@sentry/nextjs": "^7.100.1",
"@usersnap/browser": "^0.0.5",
"axios": "^1.6.7",
"cookie": "^0.6.0",
"date-fns": "^3.6.0",
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/components/molecules/FeedbackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";
import React from "react";

import { useUsersnapApi } from "../../context/usersnap";
import { Button } from "../atoms";

/**
* The FeedbackButton component renders a button that, when clicked,
* forces the Usersnap widget to open, allowing users to provide feedback or report bugs.
* @param param0 title: Button text
* @returns
*/
export function FeedbackButton({ title }) {
const usersnapApi = useUsersnapApi();

/**
* This method ignores all the display rules and opens the widget
* no matter what
*/
const handleOpenWidgetForce = () => {
usersnapApi
?.show(process.env.NEXT_PUBLIC_USERSNAP_PROJECT_API_KEY)
.then((widgetApi) => widgetApi.open({}));
};

return (
<Button onClick={handleOpenWidgetForce} variant="outlined">
{title}
</Button>
);
}
1 change: 1 addition & 0 deletions frontend/src/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export * from "./DataActionsBar";
export * from "./OrderActionsChip";
export * from "./GovernanceActionsFilters";
export * from "./GovernanceActionsSorting";
export * from "./FeedbackButton";

export * from "./types";
3 changes: 2 additions & 1 deletion frontend/src/components/organisms/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useTranslations } from "next-intl";
import { useAppContext, useModal } from "@context";
import { ICONS } from "@/constants";
import { useScreenDimension } from "@hooks";
import { FeedbackButton } from "@/components/molecules";

export const Footer = ({
showSignIn = true,
Expand Down Expand Up @@ -94,7 +95,7 @@ export const Footer = ({
<Button startIcon={<img src={ICONS.help} />} variant="text">
{t("help")}
</Button>
<Button variant="outlined">{t("feedback")}</Button>
<FeedbackButton title={t("feedback")} />
</Grid>
</Grid>

Expand Down
5 changes: 4 additions & 1 deletion frontend/src/context/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Cookies from "js-cookie";
import { isResponseErrorI } from "@utils";
import { useDocumentVisibility } from "@hooks";
import { TopBannerContextProvider } from "./topBanner";
import { UsersnapProvider } from "./usersnap";

interface AppContextType {
userSession: DecodedToken | null;
Expand Down Expand Up @@ -77,7 +78,9 @@ export function AppContextProvider({ session, children }) {
>
<ModalProvider>
<SnackbarProvider>
<TopBannerContextProvider>{children}</TopBannerContextProvider>
<TopBannerContextProvider>
<UsersnapProvider>{children}</UsersnapProvider>
</TopBannerContextProvider>
</SnackbarProvider>
</ModalProvider>
</AppContext.Provider>
Expand Down
38 changes: 38 additions & 0 deletions frontend/src/context/usersnap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";
import React, { useEffect, useState, useContext } from "react";
import { InitOptions, loadSpace, SpaceApi } from "@usersnap/browser";

export const UsersnapContext = React.createContext<SpaceApi | null>(null);

// This context is used to integrate the Usersnap widget,
// Usersnap is a tool for collecting user feedback and bug reports directly from the application
export const UsersnapProvider = ({
initParams,
children,
}: UsersnapProviderProps) => {
const [usersnapApi, setUsersnapApi] = useState<SpaceApi | null>(null);

useEffect(() => {
loadSpace(process.env.NEXT_PUBLIC_USERSNAP_GLOBAL_API_KEY).then(
(api: SpaceApi) => {
api.init(initParams);
setUsersnapApi(api);
}
);
}, [initParams]);

return (
<UsersnapContext.Provider value={usersnapApi}>
{children}
</UsersnapContext.Provider>
);
};

interface UsersnapProviderProps {
initParams?: InitOptions;
children: React.ReactNode;
}

export function useUsersnapApi() {
return useContext(UsersnapContext);
}

0 comments on commit d4d6698

Please sign in to comment.