// DEPLOY_CONFIG: {"triggers": [{"name": "notify_on_call_when_bug_becomes_critical", "on": "collection.update", "collection": "bugs", "actions": [{"type": "email", "to": "{{bug.on_call_email}}", "subject": "Critical bug alert: {{bug.title}}", "body": "Bug \"{{bug.title}}\" has been updated to critical severity.\n\nBug ID: {{bug.id}}\nSeverity: {{bug.severity}}\nStatus: {{bug.status}}\nReporter: {{bug.reporter_email}}\n\nPlease review immediately."}]}, {"name": "notify_reporter_when_bug_fixed", "on": "collection.update", "collection": "bugs", "actions": [{"type": "email", "to": "{{bug.reporter_email}}", "subject": "Bug fixed: {{bug.title}}", "body": "Your reported bug \"{{bug.title}}\" has been marked as fixed.\n\nBug ID: {{bug.id}}\nSeverity: {{bug.severity}}\nStatus: {{bug.status}}\n\nThanks for reporting it."}]}]} import { useState } from 'react'; import { useAI, useAuth, useCollection, usePresence } from '@deplixo/sdk'; import { KanbanBoard } from './components/KanbanBoard.jsx'; import { BugForm } from './components/BugForm.jsx'; import { BugDetail } from './components/BugDetail.jsx'; import { FilterBar } from './components/FilterBar.jsx'; function App() { const { user, loading: authLoading, login, logout } = useAuth(); const [showForm, setShowForm] = useState(false); const [editBug, setEditBug] = useState(null); const [viewBug, setViewBug] = useState(null); const [severityFilter, setSeverityFilter] = useState('all'); const { items, loading, add, update, remove } = useCollection('bugs', { personal: true }); const { add: saveIdentity } = useCollection('auth-identities', { personal: true }); const { generate: generateAI } = useAI(); const { update: updatePresence } = usePresence( user ? { name: user.name, avatar: user.avatar, status: viewBug ? `Viewing bug ${viewBug.id}` : 'Online', } : {} ); const handleSignIn = async () => { await login('google'); }; const handleSaveIdentity = async () => { if (!user) return; const identity = { userId: user.id, name: user.name, email: user.email, avatar: user.avatar, provider: 'google', signedInAt: Date.now(), }; await saveIdentity(identity); }; const inferCategory = async (bugData) => { const title = bugData?.title || ''; const description = bugData?.description || ''; const existingCategory = bugData?.category || ''; if (!title && !description) { return existingCategory || 'General'; } try { const result = await generateAI({ system: 'You infer the best bug category from a title and description. Return only JSON with a single key category. Choose a short category name such as UI, Backend, Performance, Security, Data, Integration, Auth, Mobile, Accessibility, or General.', user: JSON.stringify({ title, description, existingCategory }), json: true, }); const rawCategory = result && typeof result === 'object' ? result.category : ''; const category = typeof rawCategory === 'string' ? rawCategory.trim() : ''; return category || existingCategory || 'General'; } catch (error) { return existingCategory || 'General'; } }; if (authLoading) return
Signing in...
; if (!user) { return (
Team Access

🪲 Bug Tracker

Sign in with Google to create, review, and manage team bugs.

); } handleSaveIdentity(); const handleSave = async (bugData) => { const category = await inferCategory(bugData); const finalBugData = { ...bugData, category }; if (editBug) { await update(editBug.id, finalBugData); } else { await add({ ...finalBugData, status: 'new', createdAt: Date.now(), createdBy: user.id, createdByName: user.name }); } setShowForm(false); setEditBug(null); }; const handleStatusChange = async (bugId, newStatus) => { const bug = items.find(i => i.id === bugId); if (bug) await update(bugId, { ...bug.value, status: newStatus }); }; const handleEdit = (bug) => { setEditBug(bug); setShowForm(true); setViewBug(null); updatePresence({ name: user.name, avatar: user.avatar, status: 'Online', }); }; const handleDelete = async (bugId) => { await remove(bugId); setViewBug(null); }; const handleViewBug = (bug) => { setViewBug(bug); updatePresence({ name: user.name, avatar: user.avatar, status: `Viewing bug ${bug.id}`, }); }; const handleCloseBugDetail = () => { setViewBug(null); updatePresence({ name: user.name, avatar: user.avatar, status: 'Online', }); }; const filteredItems = severityFilter === 'all' ? items : items.filter(i => i.value.severity === severityFilter); return (

🪲 Bug Tracker

{items.length} bug{items.length !== 1 ? 's' : ''}
{user.avatar ? {user.name} : null} {user.name}
{showForm && ( { setShowForm(false); setEditBug(null); }} /> )} {viewBug && ( )}
); } function RichTextToolbar({ editorRef, onChange }) { const exec = (command, value = null) => { document.execCommand(command, false, value); if (editorRef?.current) editorRef.current.focus(); if (onChange) onChange(); }; const insertLink = () => { const url = window.prompt('Enter a URL'); if (!url) return; exec('createLink', url); }; return (
); } function BugViewers({ viewers }) { const visibleViewers = Array.isArray(viewers) ? viewers.filter(Boolean) : []; if (!visibleViewers.length) { return (
Currently viewing
No one else is viewing this bug right now.
); } return (
Currently viewing
{visibleViewers.map((viewer) => (
{viewer.avatar ? ( {viewer.name} ) : (
{viewer.name ? viewer.name.charAt(0).toUpperCase() : '?'}
)} {viewer.name || 'Unknown'}
))}
); } ReactDOM.createRoot(document.getElementById('root')).render();