Skip to content

Commit f222de4

Browse files
committed
Use a kapa.ai widget to help the user troubleshoot the error
1 parent 0d17a12 commit f222de4

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

packages/playground/website/src/components/site-error-modal/site-error-modal.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type {
2020
} from './types';
2121
import { getSiteErrorView } from './get-site-error-view';
2222
import type { SiteInfo } from '../../lib/state/redux/slice-sites';
23+
import { useKapaAI } from './use-kapa-ai';
2324

2425
export function SiteErrorModal({
2526
error,
@@ -38,6 +39,7 @@ export function SiteErrorModal({
3839
isSubmittingReport,
3940
handleSubmitReport,
4041
} = useErrorReporting(site);
42+
const { isConfigured: isAIConfigured, openWithQuery } = useKapaAI();
4143

4244
const helpers: PresentationHelpers = {
4345
deleteSite: () => {
@@ -142,8 +144,16 @@ export function SiteErrorModal({
142144
</p>
143145
)}
144146
</div>
145-
{view.actions.length || !view.isDeveloperError ? (
147+
{view.actions.length || !view.isDeveloperError || detailText ? (
146148
<div className={css.errorModalFooter}>
149+
{isAIConfigured && !isReporting && detailText && (
150+
<Button
151+
variant="secondary"
152+
onClick={() => openWithQuery(detailText)}
153+
>
154+
Troubleshoot with AI
155+
</Button>
156+
)}
147157
{!view.isDeveloperError &&
148158
!isReporting &&
149159
!reportSubmitted ? (
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { useEffect, useCallback, useState } from 'react';
2+
// @ts-ignore - Virtual module injected by Vite
3+
import { kapaWebsiteId } from 'virtual:kapa-ai-config';
4+
5+
declare global {
6+
interface Window {
7+
Kapa?: {
8+
open: (options?: {
9+
mode?: 'ai' | 'search';
10+
query?: string;
11+
submit?: boolean;
12+
}) => void;
13+
close: () => void;
14+
render: (options?: { onRender?: () => void }) => void;
15+
unmount: () => void;
16+
};
17+
}
18+
}
19+
20+
const KAPA_SCRIPT_ID = 'kapa-widget-script';
21+
22+
export function useKapaAI() {
23+
const [isLoaded, setIsLoaded] = useState(false);
24+
const isConfigured = Boolean(kapaWebsiteId);
25+
26+
useEffect(() => {
27+
if (!isConfigured) {
28+
return;
29+
}
30+
31+
// Check if script already exists
32+
if (document.getElementById(KAPA_SCRIPT_ID)) {
33+
if (window.Kapa) {
34+
setIsLoaded(true);
35+
}
36+
return;
37+
}
38+
39+
const script = document.createElement('script');
40+
script.id = KAPA_SCRIPT_ID;
41+
script.src = 'https://widget.kapa.ai/kapa-widget.bundle.js';
42+
script.async = true;
43+
script.setAttribute('data-website-id', kapaWebsiteId);
44+
script.setAttribute('data-project-name', 'WordPress Playground');
45+
script.setAttribute('data-project-color', '#3858e9');
46+
script.setAttribute(
47+
'data-project-logo',
48+
'https://playground.wordpress.net/logo-square.png'
49+
);
50+
script.setAttribute('data-button-hide', 'true');
51+
52+
script.onload = () => {
53+
const checkKapa = setInterval(() => {
54+
if (window.Kapa) {
55+
clearInterval(checkKapa);
56+
setIsLoaded(true);
57+
}
58+
}, 100);
59+
60+
setTimeout(() => clearInterval(checkKapa), 5000);
61+
};
62+
63+
document.body.appendChild(script);
64+
}, [isConfigured]);
65+
66+
const openWithQuery = useCallback((query: string) => {
67+
if (window.Kapa) {
68+
window.Kapa.open({
69+
mode: 'ai',
70+
query: `Suggest a solution or troubleshooting steps for the following error: ${query}`,
71+
submit: true,
72+
});
73+
74+
// Move widget container inside screen overlay so it appears on top
75+
const moveContainer = () => {
76+
const container = document.getElementById(
77+
'kapa-widget-container'
78+
);
79+
const overlay = document.querySelector(
80+
'.components-modal__screen-overlay'
81+
);
82+
if (container && overlay) {
83+
overlay.insertBefore(container, overlay.firstChild);
84+
} else {
85+
setTimeout(moveContainer, 50);
86+
}
87+
};
88+
setTimeout(moveContainer, 50);
89+
}
90+
}, []);
91+
92+
return {
93+
isConfigured,
94+
isLoaded,
95+
openWithQuery,
96+
};
97+
}

packages/playground/website/vite.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ export default defineConfig(({ command, mode }) => {
105105
content: `
106106
export const corsProxyUrl = ${JSON.stringify(corsProxyUrl || undefined)};`,
107107
}),
108+
virtualModule({
109+
name: 'kapa-ai-config',
110+
content: `
111+
export const kapaWebsiteId = ${JSON.stringify(
112+
process.env.KAPA_WEBSITE_ID || ''
113+
)};`,
114+
}),
108115
// GitHub OAuth flow
109116
{
110117
name: 'configure-server',

0 commit comments

Comments
 (0)