mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-26 23:04:57 +00:00
Generated by Spark: Oh wow it worked, now restore homepage and make this a tab
This commit is contained in:
@@ -17,12 +17,7 @@ import { initializePackageSystem } from '@/lib/package-loader'
|
||||
import type { User, AppLevel } from '@/lib/level-types'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<GitHubActionsFetcher />
|
||||
<Toaster />
|
||||
</>
|
||||
)
|
||||
return <AppOriginal />
|
||||
}
|
||||
|
||||
function AppOriginal() {
|
||||
|
||||
@@ -80,150 +80,148 @@ export function GitHubActionsFetcher() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background p-6">
|
||||
<div className="max-w-7xl mx-auto space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-foreground">GitHub Actions Monitor</h1>
|
||||
<p className="text-muted-foreground mt-2">
|
||||
Repository: <code className="text-sm bg-muted px-2 py-1 rounded">johndoe6345789/metabuilder</code>
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
onClick={fetchGitHubActions}
|
||||
disabled={isLoading}
|
||||
size="lg"
|
||||
>
|
||||
<ArrowClockwise className={isLoading ? 'animate-spin' : ''} />
|
||||
{isLoading ? 'Fetching...' : 'Refresh'}
|
||||
</Button>
|
||||
<div className="space-y-6 py-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-foreground">GitHub Actions Monitor</h2>
|
||||
<p className="text-muted-foreground mt-2">
|
||||
Repository: <code className="text-sm bg-muted px-2 py-1 rounded">johndoe6345789/metabuilder</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{needsAuth && (
|
||||
<Alert>
|
||||
<Info className="text-blue-600" />
|
||||
<AlertTitle>Authentication Note</AlertTitle>
|
||||
<AlertDescription>
|
||||
This app uses the GitHub API to fetch workflow data. The public API allows anonymous access with rate limits.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{lastFetched && (
|
||||
<Alert>
|
||||
<CheckCircle className="text-green-600" />
|
||||
<AlertTitle>Last Fetched</AlertTitle>
|
||||
<AlertDescription>
|
||||
{lastFetched.toLocaleString()}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<Alert variant="destructive">
|
||||
<XCircle />
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertDescription>{error}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
Workflow Runs
|
||||
<a
|
||||
href="https://github.com/johndoe6345789/metabuilder/actions"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm font-normal text-primary hover:underline flex items-center gap-2"
|
||||
>
|
||||
Open in GitHub
|
||||
<ArrowSquareOut size={16} />
|
||||
</a>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Recent workflow runs via GitHub REST API
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<div className="space-y-3">
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
</div>
|
||||
) : data && data.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{data.map((run) => (
|
||||
<Card key={run.id} className="border-l-4" style={{ borderLeftColor: run.conclusion === 'success' ? '#16a34a' : '#dc2626' }}>
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
{getStatusIcon(run.status, run.conclusion)}
|
||||
<h3 className="font-semibold text-foreground truncate">{run.name}</h3>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Branch:</span>
|
||||
<code className="bg-muted px-1 rounded text-xs">{run.head_branch}</code>
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Event:</span>
|
||||
<span>{run.event}</span>
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Status:</span>
|
||||
<span className={getStatusColor(run.status, run.conclusion)}>
|
||||
{run.status === 'completed' ? run.conclusion : run.status}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
Updated: {new Date(run.updated_at).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
asChild
|
||||
>
|
||||
<a
|
||||
href={run.html_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
View
|
||||
<ArrowSquareOut size={14} />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
<div className="text-center pt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const jsonData = JSON.stringify(data, null, 2)
|
||||
navigator.clipboard.writeText(jsonData)
|
||||
toast.success('JSON data copied to clipboard')
|
||||
}}
|
||||
>
|
||||
Copy All as JSON
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center text-muted-foreground py-8">
|
||||
No workflow runs found. Click refresh to fetch data.
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Button
|
||||
onClick={fetchGitHubActions}
|
||||
disabled={isLoading}
|
||||
size="lg"
|
||||
>
|
||||
<ArrowClockwise className={isLoading ? 'animate-spin' : ''} />
|
||||
{isLoading ? 'Fetching...' : 'Refresh'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{needsAuth && (
|
||||
<Alert>
|
||||
<Info className="text-blue-600" />
|
||||
<AlertTitle>Authentication Note</AlertTitle>
|
||||
<AlertDescription>
|
||||
This app uses the GitHub API to fetch workflow data. The public API allows anonymous access with rate limits.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{lastFetched && (
|
||||
<Alert>
|
||||
<CheckCircle className="text-green-600" />
|
||||
<AlertTitle>Last Fetched</AlertTitle>
|
||||
<AlertDescription>
|
||||
{lastFetched.toLocaleString()}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<Alert variant="destructive">
|
||||
<XCircle />
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertDescription>{error}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
Workflow Runs
|
||||
<a
|
||||
href="https://github.com/johndoe6345789/metabuilder/actions"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm font-normal text-primary hover:underline flex items-center gap-2"
|
||||
>
|
||||
Open in GitHub
|
||||
<ArrowSquareOut size={16} />
|
||||
</a>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Recent workflow runs via GitHub REST API
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<div className="space-y-3">
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-20 w-full" />
|
||||
</div>
|
||||
) : data && data.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{data.map((run) => (
|
||||
<Card key={run.id} className="border-l-4" style={{ borderLeftColor: run.conclusion === 'success' ? '#16a34a' : '#dc2626' }}>
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
{getStatusIcon(run.status, run.conclusion)}
|
||||
<h3 className="font-semibold text-foreground truncate">{run.name}</h3>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Branch:</span>
|
||||
<code className="bg-muted px-1 rounded text-xs">{run.head_branch}</code>
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Event:</span>
|
||||
<span>{run.event}</span>
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="font-medium">Status:</span>
|
||||
<span className={getStatusColor(run.status, run.conclusion)}>
|
||||
{run.status === 'completed' ? run.conclusion : run.status}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
Updated: {new Date(run.updated_at).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
asChild
|
||||
>
|
||||
<a
|
||||
href={run.html_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
View
|
||||
<ArrowSquareOut size={14} />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
<div className="text-center pt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const jsonData = JSON.stringify(data, null, 2)
|
||||
navigator.clipboard.writeText(jsonData)
|
||||
toast.success('JSON data copied to clipboard')
|
||||
}}
|
||||
>
|
||||
Copy All as JSON
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center text-muted-foreground py-8">
|
||||
No workflow runs found. Click refresh to fetch data.
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import { HeroSection } from './level1/HeroSection'
|
||||
import { FeaturesSection } from './level1/FeaturesSection'
|
||||
import { ContactSection } from './level1/ContactSection'
|
||||
import { AppFooter } from './shared/AppFooter'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { GitHubActionsFetcher } from './GitHubActionsFetcher'
|
||||
|
||||
interface Level1Props {
|
||||
onNavigate: (level: number) => void
|
||||
@@ -102,25 +104,40 @@ export function Level1({ onNavigate }: Level1Props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<HeroSection onNavigate={onNavigate} />
|
||||
<FeaturesSection />
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-6">
|
||||
<Tabs defaultValue="home" className="w-full">
|
||||
<TabsList className="grid w-full max-w-md mx-auto grid-cols-2 mb-8">
|
||||
<TabsTrigger value="home">Home</TabsTrigger>
|
||||
<TabsTrigger value="github-actions">GitHub Actions</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="home" className="mt-0">
|
||||
<HeroSection onNavigate={onNavigate} />
|
||||
<FeaturesSection />
|
||||
|
||||
<section id="about" className="bg-muted/30 py-20">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6">
|
||||
<h2 className="text-3xl font-bold">About MetaBuilder</h2>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
MetaBuilder is a revolutionary platform that lets you build entire application stacks
|
||||
through visual interfaces. From public websites to complex admin panels, everything
|
||||
is generated from declarative configurations, workflows, and embedded scripts.
|
||||
</p>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Whether you're a designer who wants to create without code, or a developer who wants
|
||||
to work at a higher level of abstraction, MetaBuilder adapts to your needs.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="about" className="bg-muted/30 py-20 -mx-4 sm:-mx-6 lg:-mx-8 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-4xl mx-auto text-center space-y-6">
|
||||
<h2 className="text-3xl font-bold">About MetaBuilder</h2>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
MetaBuilder is a revolutionary platform that lets you build entire application stacks
|
||||
through visual interfaces. From public websites to complex admin panels, everything
|
||||
is generated from declarative configurations, workflows, and embedded scripts.
|
||||
</p>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Whether you're a designer who wants to create without code, or a developer who wants
|
||||
to work at a higher level of abstraction, MetaBuilder adapts to your needs.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ContactSection />
|
||||
<ContactSection />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="github-actions" className="mt-0">
|
||||
<GitHubActionsFetcher />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<AppFooter />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user