3c95281119
- 3-Spalten-Layout: Missions/Feed | Team Network | Chat/Queue - AI Team Network (Herzstück): Iris + 4 Agenten mit SVG-Linien - AgentNode: Workload-Ring, Pulse-Animation, Farbcodierung - AgentModal: Task, Goal, Progress, Working Feed - MissionCard: Glass-Morphism, Progress-Bar, Status-Badges - ChatPanel: Iris Chat mit Focus-Banner, Auto-Scroll - QueuePanel: Drag&Drop, Prioritäten, Force-Execute - Composables: useTimer, useDashboardData
38 lines
890 B
TypeScript
38 lines
890 B
TypeScript
import { ref, onMounted, onUnmounted } from 'vue'
|
|
|
|
export function useTimer() {
|
|
const elapsed = ref(0)
|
|
let interval: ReturnType<typeof setInterval> | null = null
|
|
|
|
function start() {
|
|
if (interval !== null) return
|
|
const startTime = Date.now()
|
|
elapsed.value = 0
|
|
interval = setInterval(() => {
|
|
elapsed.value = Math.floor((Date.now() - startTime) / 1000)
|
|
}, 1000)
|
|
}
|
|
|
|
function stop() {
|
|
if (interval !== null) {
|
|
clearInterval(interval)
|
|
interval = null
|
|
}
|
|
}
|
|
|
|
function format(minutes: number, seconds: number): string {
|
|
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
|
}
|
|
|
|
const formatted = (): string => {
|
|
const m = Math.floor(elapsed.value / 60)
|
|
const s = elapsed.value % 60
|
|
return format(m, s)
|
|
}
|
|
|
|
onMounted(start)
|
|
onUnmounted(stop)
|
|
|
|
return { elapsed, formatted, start, stop }
|
|
}
|