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:
Wikid82
2025-11-18 13:11:11 -05:00
parent b9dcc6c347
commit e58fcb714d
76 changed files with 16989 additions and 99 deletions

View 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,
}
}