Generated by Spark: Oh wow it worked, now restore homepage and make this a tab

This commit is contained in:
2025-12-24 20:52:17 +00:00
parent f69faf8086
commit 4ac5c16fe3
3 changed files with 175 additions and 165 deletions

View File

@@ -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() {

View File

@@ -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>
)
}

View File

@@ -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>