docs: comprehensive documentation polish & CI/CD automation
Major Updates: - Rewrote all docs in beginner-friendly 'ELI5' language - Created docs index with user journey navigation - Added complete getting-started guide for novice users - Set up GitHub Container Registry (GHCR) automation - Configured GitHub Pages deployment for documentation Documentation: - docs/index.md - Central navigation hub - docs/getting-started.md - Step-by-step beginner guide - docs/github-setup.md - CI/CD setup instructions - README.md - Complete rewrite in accessible language - CONTRIBUTING.md - Contributor guidelines - Multiple comprehensive API and schema docs CI/CD Workflows: - .github/workflows/docker-build.yml - Multi-platform builds to GHCR - .github/workflows/docs.yml - Automated docs deployment to Pages - Supports main (latest), development (dev), and version tags - Automated testing of built images - Beautiful documentation site with dark theme Benefits: - Zero barrier to entry for new users - Automated Docker builds (AMD64 + ARM64) - Professional documentation site - No Docker Hub account needed (uses GHCR) - Complete CI/CD pipeline All 7 implementation phases complete - project is production ready!
This commit is contained in:
116
frontend/src/hooks/useImport.ts
Normal file
116
frontend/src/hooks/useImport.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { importAPI } from '../services/api'
|
||||
|
||||
interface ImportSession {
|
||||
uuid: string
|
||||
filename?: string
|
||||
state: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
interface ImportPreview {
|
||||
hosts: any[]
|
||||
conflicts: string[]
|
||||
errors: string[]
|
||||
}
|
||||
|
||||
export function useImport() {
|
||||
const [session, setSession] = useState<ImportSession | null>(null)
|
||||
const [preview, setPreview] = useState<ImportPreview | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [polling, setPolling] = useState(false)
|
||||
|
||||
const checkStatus = useCallback(async () => {
|
||||
try {
|
||||
const status = await importAPI.status()
|
||||
if (status.has_pending && status.session) {
|
||||
setSession(status.session)
|
||||
if (status.session.state === 'reviewing') {
|
||||
const previewData = await importAPI.preview()
|
||||
setPreview(previewData)
|
||||
}
|
||||
} else {
|
||||
setSession(null)
|
||||
setPreview(null)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to check import status:', err)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
checkStatus()
|
||||
}, [checkStatus])
|
||||
|
||||
useEffect(() => {
|
||||
if (polling && session?.state === 'reviewing') {
|
||||
const interval = setInterval(checkStatus, 3000)
|
||||
return () => clearInterval(interval)
|
||||
}
|
||||
}, [polling, session?.state, checkStatus])
|
||||
|
||||
const upload = async (content: string, filename?: string) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const result = await importAPI.upload(content, filename)
|
||||
setSession(result.session)
|
||||
setPolling(true)
|
||||
await checkStatus()
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to upload Caddyfile')
|
||||
throw err
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const commit = async (resolutions: Record<string, string>) => {
|
||||
if (!session) throw new Error('No active session')
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
await importAPI.commit(session.uuid, resolutions)
|
||||
setSession(null)
|
||||
setPreview(null)
|
||||
setPolling(false)
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to commit import')
|
||||
throw err
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const cancel = async () => {
|
||||
if (!session) return
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
await importAPI.cancel(session.uuid)
|
||||
setSession(null)
|
||||
setPreview(null)
|
||||
setPolling(false)
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to cancel import')
|
||||
throw err
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
session,
|
||||
preview,
|
||||
loading,
|
||||
error,
|
||||
upload,
|
||||
commit,
|
||||
cancel,
|
||||
refresh: checkStatus,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user