feat: sentry bug reports and integration (glitchtip)
This commit is contained in:
60
App.tsx
60
App.tsx
@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
||||
import { Dialog } from "@headlessui/react";
|
||||
import { Cog6ToothIcon } from "@heroicons/react/24/outline";
|
||||
import { Cog6ToothIcon, ChatBubbleLeftRightIcon } from "@heroicons/react/24/outline";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { Exercise, CheckResult, ExercisePartType } from './types';
|
||||
import { swaExercises1 } from './data/swa_exercises.1';
|
||||
import { swaExercises2 } from './data/swa_exercises.2';
|
||||
@ -539,6 +540,16 @@ const allSwaExercises: Exercise[] = [
|
||||
export default function App() {
|
||||
const [exercises, setExercises] = useState<Exercise[]>([]);
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const [showFeedback, setShowFeedback] = useState(false);
|
||||
const [feedbackMessage, setFeedbackMessage] = useState('');
|
||||
|
||||
const handleFeedbackSubmit = () => {
|
||||
Sentry.captureFeedback({
|
||||
message: feedbackMessage,
|
||||
});
|
||||
setFeedbackMessage('');
|
||||
setShowFeedback(false);
|
||||
};
|
||||
|
||||
// --- API KEY STATE ---
|
||||
const [apiKey, setApiKey] = useState<string>('');
|
||||
@ -592,6 +603,14 @@ export default function App() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col p-4 md:p-8">
|
||||
{/* Feedback Button */}
|
||||
<button
|
||||
className="fixed top-4 right-16 z-50 bg-white rounded-full p-2 shadow hover:bg-slate-100 transition"
|
||||
aria-label="Feedback"
|
||||
onClick={() => setShowFeedback(true)}
|
||||
>
|
||||
<ChatBubbleLeftRightIcon className="w-7 h-7 text-slate-600" />
|
||||
</button>
|
||||
{/* Settings Button */}
|
||||
<button
|
||||
className="fixed top-4 right-4 z-50 bg-white rounded-full p-2 shadow hover:bg-slate-100 transition"
|
||||
@ -642,6 +661,45 @@ export default function App() {
|
||||
</Dialog.Panel>
|
||||
</div>
|
||||
</Dialog>
|
||||
{/* Feedback Modal */}
|
||||
<Dialog open={showFeedback} onClose={() => setShowFeedback(false)} className="relative z-50">
|
||||
<div className="fixed inset-0 bg-black/30" aria-hidden="true" />
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4">
|
||||
<Dialog.Panel className="bg-white rounded-lg shadow-xl p-8 max-w-md w-full">
|
||||
<Dialog.Title className="font-bold text-lg mb-4 flex items-center gap-2">
|
||||
<ChatBubbleLeftRightIcon className="w-6 h-6 text-blue-600" />
|
||||
Feedback?
|
||||
</Dialog.Title>
|
||||
<div className="mb-4">
|
||||
<p>
|
||||
Hi :)<br/>Hast du Feedback, Aufgabenideen, oder gab es einen Bug? Sag mir gern bescheid, und ich schau, was ich tun kann - yandrik
|
||||
</p>
|
||||
<textarea
|
||||
className="w-full border rounded px-3 py-2 text-slate-800"
|
||||
value={feedbackMessage}
|
||||
onChange={e => setFeedbackMessage(e.target.value)}
|
||||
placeholder="Ich finde, dass..."
|
||||
rows={5}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2">
|
||||
<button
|
||||
className="px-4 py-2 rounded bg-slate-200 text-slate-700 hover:bg-slate-300"
|
||||
onClick={() => setShowFeedback(false)}
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button
|
||||
className="px-4 py-2 rounded bg-blue-600 text-white font-bold hover:bg-blue-700"
|
||||
onClick={handleFeedbackSubmit}
|
||||
disabled={!feedbackMessage.trim()}
|
||||
>
|
||||
Senden
|
||||
</button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</div>
|
||||
</Dialog>
|
||||
<header className="mb-6 flex-shrink-0">
|
||||
<h1 className="text-3xl font-serif font-bold text-slate-800">SWA Trainer</h1>
|
||||
<p className="text-slate-500">Interaktive Übungen zur Vorbereitung auf die SWA-Klausur</p>
|
||||
|
11
index.tsx
11
index.tsx
@ -2,6 +2,17 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
import * as Sentry from "@sentry/react";
|
||||
|
||||
Sentry.init({
|
||||
dsn: "https://2851a11b9f1b4715b389979628da322f@glitchtip.yandrik.dev/3",
|
||||
integrations: [
|
||||
Sentry.feedbackIntegration({
|
||||
// Additional SDK configuration goes in here, for example:
|
||||
colorScheme: "system",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const rootElement = document.getElementById('root');
|
||||
if (!rootElement) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
"@google/genai": "latest",
|
||||
"@headlessui/react": "^2.2.4",
|
||||
"@heroicons/react": "^2.2.0",
|
||||
"@sentry/react": "^9.36.0",
|
||||
"diff": "5.2.0",
|
||||
"mermaid": "^11.8.1",
|
||||
"prismjs": "1.29.0",
|
||||
|
80
pnpm-lock.yaml
generated
80
pnpm-lock.yaml
generated
@ -17,6 +17,9 @@ importers:
|
||||
'@heroicons/react':
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0(react@19.1.0)
|
||||
'@sentry/react':
|
||||
specifier: ^9.36.0
|
||||
version: 9.36.0(react@19.1.0)
|
||||
diff:
|
||||
specifier: 5.2.0
|
||||
version: 5.2.0
|
||||
@ -434,6 +437,36 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@sentry-internal/browser-utils@9.36.0':
|
||||
resolution: {integrity: sha512-4cGT7c4kr4DMRlcnErgWiL/uLwHvD8A52w6ffJkT/Bj7olSUjFCo8RKIEsDiJqk8No3yfoS6dRbudMZUIFuDTA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry-internal/feedback@9.36.0':
|
||||
resolution: {integrity: sha512-0FNKlP2/CWbitAqtLKVPuSqMs8h7jMJm812wSA0gPpCBVMoX+mWEKQh3pYHYekHVfI0muieX9CWYlup0McXaJA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry-internal/replay-canvas@9.36.0':
|
||||
resolution: {integrity: sha512-/RrYKvQ80gzjEJoHWMFXqYPlQS8ovEUWG2KeSJQdFtvL+/M/864jfxTA21hgHJC/5GbnOq4V541C1P5YVXwg6w==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry-internal/replay@9.36.0':
|
||||
resolution: {integrity: sha512-BKxDz4r7bC23d9+zx3a0qkjWLa4zgE/8tXSfcSVYwhczEzTNXYOPxIodYm2IzgVgN9NwUE1m9Cf+/xlKKQLyFQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry/browser@9.36.0':
|
||||
resolution: {integrity: sha512-DCn6VoJCWMjZm5sOfD2+2EgEVdr+H/8Hqs080ruWZo1MZzIUmF1+qnG7AtYeIlm93OydU0PLjvYeWo0zttgGvg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry/core@9.36.0':
|
||||
resolution: {integrity: sha512-LU6EmsXPxi8QFkrx0fCqhXicsJA6uUWCD0VrxePZzs+Xs0SgVNDxOgRELVrZa4LPomQJBR5wmm3Duozp9JkHcQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@sentry/react@9.36.0':
|
||||
resolution: {integrity: sha512-SCl3jxZ5fEw+r+7Eo95NgI4cNs7r8Z2ppv0/iyK6qQE/CCTJfBDgnJf6Af/NupO2V/tkfdEJcsb+QNLAu91qvA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
react: ^16.14.0 || 17.x || 18.x || 19.x
|
||||
|
||||
'@swc/helpers@0.5.17':
|
||||
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
|
||||
|
||||
@ -919,6 +952,9 @@ packages:
|
||||
hast-util-whitespace@3.0.0:
|
||||
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
|
||||
html-url-attributes@3.0.1:
|
||||
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
||||
|
||||
@ -1209,6 +1245,9 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^19.1.0
|
||||
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
react-markdown@9.1.0:
|
||||
resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==}
|
||||
peerDependencies:
|
||||
@ -1727,6 +1766,41 @@ snapshots:
|
||||
'@rollup/rollup-win32-x64-msvc@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@sentry-internal/browser-utils@9.36.0':
|
||||
dependencies:
|
||||
'@sentry/core': 9.36.0
|
||||
|
||||
'@sentry-internal/feedback@9.36.0':
|
||||
dependencies:
|
||||
'@sentry/core': 9.36.0
|
||||
|
||||
'@sentry-internal/replay-canvas@9.36.0':
|
||||
dependencies:
|
||||
'@sentry-internal/replay': 9.36.0
|
||||
'@sentry/core': 9.36.0
|
||||
|
||||
'@sentry-internal/replay@9.36.0':
|
||||
dependencies:
|
||||
'@sentry-internal/browser-utils': 9.36.0
|
||||
'@sentry/core': 9.36.0
|
||||
|
||||
'@sentry/browser@9.36.0':
|
||||
dependencies:
|
||||
'@sentry-internal/browser-utils': 9.36.0
|
||||
'@sentry-internal/feedback': 9.36.0
|
||||
'@sentry-internal/replay': 9.36.0
|
||||
'@sentry-internal/replay-canvas': 9.36.0
|
||||
'@sentry/core': 9.36.0
|
||||
|
||||
'@sentry/core@9.36.0': {}
|
||||
|
||||
'@sentry/react@9.36.0(react@19.1.0)':
|
||||
dependencies:
|
||||
'@sentry/browser': 9.36.0
|
||||
'@sentry/core': 9.36.0
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 19.1.0
|
||||
|
||||
'@swc/helpers@0.5.17':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@ -2291,6 +2365,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
|
||||
html-url-attributes@3.0.1: {}
|
||||
|
||||
https-proxy-agent@7.0.6:
|
||||
@ -2814,6 +2892,8 @@ snapshots:
|
||||
react: 19.1.0
|
||||
scheduler: 0.26.0
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react-markdown@9.1.0(@types/react@19.1.8)(react@19.1.0):
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
|
Reference in New Issue
Block a user