Files
play-life/play-life-web/src/components/TodoistIntegration.jsx
poignatov edc29fbd97
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 41s
v2.0.4: Fix webhook error handling and logging
- Webhooks now return 200 OK even on errors (to prevent retries)
- Improved error handling with proper JSON responses
- Enhanced logging for webhook debugging
- Supervisor logs now visible in docker logs (stdout/stderr)
- Fixed TodoistIntegration error display in UI
2026-01-01 18:50:55 +03:00

111 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react'
import { useAuth } from './auth/AuthContext'
import './Integrations.css'
function TodoistIntegration({ onBack }) {
const { authFetch } = useAuth()
const [webhookURL, setWebhookURL] = useState('')
const [loading, setLoading] = useState(true)
const [copied, setCopied] = useState(false)
const [error, setError] = useState('')
useEffect(() => {
fetchWebhookURL()
}, [])
const fetchWebhookURL = async () => {
try {
setLoading(true)
setError('')
const response = await authFetch('/api/integrations/todoist/webhook-url')
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new Error(errorData.error || 'Ошибка при загрузке URL webhook')
}
const data = await response.json()
if (data.webhook_url) {
setWebhookURL(data.webhook_url)
} else {
throw new Error('Webhook URL не найден в ответе')
}
} catch (error) {
console.error('Error fetching webhook URL:', error)
setError(error.message || 'Не удалось загрузить webhook URL')
} finally {
setLoading(false)
}
}
const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(webhookURL)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (error) {
console.error('Error copying to clipboard:', error)
}
}
return (
<div className="p-4 md:p-6">
<button className="close-x-button" onClick={onBack} title="Закрыть">
</button>
<h1 className="text-2xl font-bold mb-6">TODOist интеграция</h1>
<div className="bg-white rounded-lg shadow-md p-6 mb-6">
<h2 className="text-lg font-semibold mb-4">Webhook URL</h2>
{loading ? (
<div className="text-gray-500">Загрузка...</div>
) : error ? (
<div className="text-red-600 mb-4">
<p className="mb-2">{error}</p>
<button
onClick={fetchWebhookURL}
className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors"
>
Попробовать снова
</button>
</div>
) : (
<div className="flex items-center gap-2">
<input
type="text"
value={webhookURL}
readOnly
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg bg-gray-50 text-sm"
/>
<button
onClick={copyToClipboard}
className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors whitespace-nowrap"
>
{copied ? 'Скопировано!' : 'Копировать'}
</button>
</div>
)}
</div>
<div className="bg-blue-50 border border-blue-200 rounded-lg p-6">
<h3 className="text-lg font-semibold mb-3 text-blue-900">
Как использовать в приложении TODOist
</h3>
<ol className="list-decimal list-inside space-y-2 text-gray-700">
<li>Откройте приложение TODOist на вашем устройстве</li>
<li>Перейдите в настройки проекта или задачи</li>
<li>Найдите раздел "Интеграции" или "Webhooks"</li>
<li>Вставьте скопированный URL webhook в соответствующее поле</li>
<li>Сохраните настройки</li>
<li>
Теперь при закрытии задач в TODOist они будут автоматически
обрабатываться системой
</li>
</ol>
</div>
</div>
)
}
export default TodoistIntegration