aura-ai
Version:
AI-powered marketing strategist CLI tool for developers
182 lines (160 loc) • 5.57 kB
JSX
import React, { useState, useEffect } from 'react'
import { Box, Text, Newline } from 'ink'
import { Spinner, Alert } from '@inkjs/ui'
import SelectInput from 'ink-select-input'
import gitService from '../services/gitService.js'
import syncAIService from '../services/syncAIService.js'
/**
* Sync Page - AI-Generated Daily Progress Report
*/
const SyncPage = ({ onBack }) => {
const [loading, setLoading] = useState(true)
const [report, setReport] = useState(null)
const [error, setError] = useState(null)
const [showMenu, setShowMenu] = useState(false)
const [commits, setCommits] = useState([])
useEffect(() => {
loadReport()
}, [])
const loadReport = async () => {
setLoading(true)
setError(null)
try {
// Get today's commits
const todayCommits = await gitService.getTodayCommits()
setCommits(todayCommits)
// Generate AI report
const formattedCommits = gitService.formatCommitsForAI(todayCommits)
const aiReport = await syncAIService.generateDailyReport(formattedCommits)
setReport(aiReport)
setShowMenu(true)
} catch (err) {
setError('Failed to generate report: ' + err.message)
} finally {
setLoading(false)
}
}
const menuItems = [
{ label: '📋 Copy as Markdown', value: 'copy' },
{ label: '🔄 Refresh', value: 'refresh' },
{ label: '← Back to Main Menu', value: 'back' }
]
const handleSelect = async (item) => {
if (item.value === 'back') {
onBack()
} else if (item.value === 'refresh') {
setShowMenu(false)
await loadReport()
} else if (item.value === 'copy') {
try {
const { exec } = await import('child_process')
const { promisify } = await import('util')
const execAsync = promisify(exec)
// Copy to clipboard based on OS
const platform = process.platform
const markdown = report.markdown
if (platform === 'darwin') {
// macOS
await execAsync(`echo "${markdown.replace(/"/g, '\\"').replace(/\$/g, '\\$')}" | pbcopy`)
} else if (platform === 'linux') {
// Linux (requires xclip)
await execAsync(`echo "${markdown.replace(/"/g, '\\"').replace(/\$/g, '\\$')}" | xclip -selection clipboard`)
} else if (platform === 'win32') {
// Windows
await execAsync(`echo "${markdown.replace(/"/g, '\\"').replace(/\$/g, '\\$')}" | clip`)
}
setError(`✅ Report copied to clipboard!`)
setTimeout(() => setError(null), 3000)
} catch (err) {
setError('Failed to copy: ' + err.message)
setTimeout(() => setError(null), 3000)
}
}
}
if (loading) {
return (
<Box flexDirection="column" padding={1}>
<Box paddingY={1} paddingX={2} borderColor='blue' borderStyle='round'>
<Text>
<Text bold>🤖 AI Daily Sync</Text> - Generating Intelligence Report...
</Text>
</Box>
<Box marginTop={2} paddingLeft={2}>
<Spinner label="AI is analyzing your commits..." />
</Box>
</Box>
)
}
return (
<Box flexDirection="column" padding={1}>
<Box paddingY={1} paddingX={2} borderColor='blue' borderStyle='round'>
<Text>
<Text bold>🤖 AI Daily Sync</Text> - Progress Intelligence
</Text>
</Box>
{error && (
<Box marginTop={1}>
<Alert variant={error.startsWith('✅') ? 'success' : 'error'}>
{error}
</Alert>
</Box>
)}
{report && (
<>
{/* AI Summary */}
<Box marginTop={2} paddingLeft={1}>
<Text color="yellow" bold>📊 Executive Summary</Text>
</Box>
<Box marginTop={1} paddingLeft={1}>
<Text>{report.summary}</Text>
</Box>
{/* Key Highlights */}
{report.highlights && report.highlights.length > 0 && (
<>
<Box marginTop={2} paddingLeft={1}>
<Text color="cyan" bold>✨ Key Achievements</Text>
</Box>
{report.highlights.map((highlight, index) => (
<Box key={index} paddingLeft={2}>
<Text>• {highlight}</Text>
</Box>
))}
</>
)}
{/* Commit Count */}
{commits.length > 0 && (
<Box marginTop={2} paddingLeft={1}>
<Text dimColor>
Based on {commits.length} commits today
</Text>
</Box>
)}
{/* Menu Options */}
{showMenu && (
<>
<Box marginTop={2} paddingLeft={1}>
<Text color="gray">What would you like to do?</Text>
</Box>
<Box marginTop={1}>
<SelectInput items={menuItems} onSelect={handleSelect} />
</Box>
</>
)}
</>
)}
{/* Empty State */}
{commits.length === 0 && (
<Box marginTop={2} paddingLeft={1}>
<Box flexDirection="column">
<Text color="gray">No commits found today yet!</Text>
<Newline />
<Text color="gray">Start working on your project and come back later.</Text>
<Newline />
<Text dimColor>💡 AI will analyze and summarize your work intelligently.</Text>
</Box>
</Box>
)}
</Box>
)
}
export default SyncPage