import { Card, CardContent, CardHeader, Link, List, ListItem, TextField, Typography, } from "@material-ui/core"; import Skeleton from "@material-ui/lab/Skeleton"; import { useAppBridge, withAuthorization } from "@saleor/app-sdk/app-bridge"; import { SALEOR_API_URL_HEADER, SALEOR_AUTHORIZATION_BEARER_HEADER } from "@saleor/app-sdk/const"; import { ConfirmButton, ConfirmButtonTransitionState, makeStyles } from "@saleor/macaw-ui"; import { ChangeEvent, ReactElement, SyntheticEvent, useEffect, useState } from "react"; import AccessWarning from "../components/AccessWarning/AccessWarning"; import { ConfigurationError } from "../components/ConfigurationError/ConfigurationError"; import useAppApi from "../hooks/useAppApi"; import useDashboardNotifier from "../utils/useDashboardNotifier"; import { AppColumnsLayout } from "../components/AppColumnsLayout/AppColumnsLayout"; interface ConfigurationField { key: string; value: string; } const useStyles = makeStyles((theme) => ({ confirmButton: { marginLeft: "auto", }, fieldContainer: { marginBottom: theme.spacing(2), }, additionalInfo: { marginBottom: theme.spacing(3), }, })); function Configuration() { const classes = useStyles(); const { appBridgeState } = useAppBridge(); const [notify] = useDashboardNotifier(); const [configuration, setConfiguration] = useState(); const [transitionState, setTransitionState] = useState("default"); const { data: configurationData, error } = useAppApi<{ data: ConfigurationField[] }>({ url: "/api/configuration", }); useEffect(() => { if (configurationData && !configuration) { setConfiguration(configurationData.data); } }, [configurationData, configuration]); const handleSubmit = (event: SyntheticEvent) => { event.preventDefault(); setTransitionState("loading"); fetch("/api/configuration", { method: "POST", headers: [ ["content-type", "application/json"], [SALEOR_API_URL_HEADER, appBridgeState?.saleorApiUrl!], [SALEOR_AUTHORIZATION_BEARER_HEADER, appBridgeState?.token!], ], body: JSON.stringify({ data: configuration }), }) .then(async (response) => { setTransitionState(response.status === 200 ? "success" : "error"); await notify({ status: "success", title: "Success", text: "Configuration updated successfully", }); }) .catch(async () => { setTransitionState("error"); await notify({ status: "error", title: "Configuration update failed", }); }); }; const onChange = (event: ChangeEvent) => { const { name, value } = event.target as HTMLInputElement; setConfiguration((prev) => prev!.map((prevField) => (prevField.key === name ? { ...prevField, value } : prevField)) ); }; if (error) { console.error("Can't establish connection with the App API: ", error); return ; } if (configuration === undefined) { return ; } return (
{configuration!.map(({ key, value }) => (
))}

This webhook will be called when new order is created and `order_created` event is triggered.

); } function Instructions() { const { appBridge } = useAppBridge(); const { data } = useAppApi({ url: "/api/slack-app-manifest", }); const slackUrl = new URL("https://api.slack.com/apps"); slackUrl.searchParams.append("new_app", "1"); slackUrl.searchParams.append("manifest_json", JSON.stringify(data)); const openExternalUrl = (to: string) => { appBridge?.dispatch({ type: "redirect", payload: { newContext: true, actionId: "redirect_from_slack_app", to, }, }); }; return ( <> How to configure { e.preventDefault(); openExternalUrl(slackUrl.href); }} href={slackUrl.href} > Install Slack application Copy incoming Webhook URL from Slack app configuration and paste it below into `WEBHOOK_URL` field Save configuration Useful links { e.preventDefault(); openExternalUrl("https://github.com/saleor/saleor-app-slack"); }} href="https://github.com/saleor/saleor-app-slack" > Visit repository & readme { e.preventDefault(); openExternalUrl("https://api.slack.com/messaging/webhooks"); }} href="https://api.slack.com/messaging/webhooks" > Read about Slack apps that use incoming webhooks ); } const ConfigurationWithAuth = withAuthorization({ notIframe: , unmounted: null, noDashboardToken: , dashboardTokenInvalid: , })(Configuration); ConfigurationWithAuth.getLayout = (page: ReactElement) => (
{page} ); export default ConfigurationWithAuth;