Merge branch 'main' into codex/split-groupnode-and-ideanode-into-separate-files

This commit is contained in:
2026-01-18 00:16:51 +00:00
committed by GitHub
51 changed files with 1538 additions and 2062 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
import { FileCode, CheckCircle, Sparkle } from '@phosphor-icons/react'
export function AgentFileItem({ filename, path, description, features }: {
filename: string
path: string
description: string
features: string[]
}) {
return (
<div className="space-y-3 border-l-2 border-accent pl-4">
<div className="space-y-1">
<div className="flex items-center gap-2">
<FileCode size={18} className="text-accent" />
<code className="text-sm font-semibold text-accent">{filename}</code>
</div>
<p className="text-xs text-muted-foreground font-mono">{path}</p>
<p className="text-sm text-foreground/90">{description}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">Key Features:</p>
<ul className="space-y-1">
{features.map((feature) => (
<li key={feature} className="text-sm text-foreground/80 flex items-start gap-2">
<CheckCircle size={14} weight="fill" className="text-accent mt-1 flex-shrink-0" />
<span>{feature}</span>
</li>
))}
</ul>
</div>
</div>
)
}
export function IntegrationPoint({ component, capabilities }: { component: string; capabilities: string[] }) {
return (
<div className="space-y-2 border rounded-lg p-4 bg-card">
<h4 className="font-semibold text-sm flex items-center gap-2">
<Sparkle size={16} weight="duotone" className="text-accent" />
{component}
</h4>
<ul className="space-y-1">
{capabilities.map((capability) => (
<li key={capability} className="text-sm text-muted-foreground flex items-start gap-2">
<span className="text-accent"></span>
<span>{capability}</span>
</li>
))}
</ul>
</div>
)
}

View File

@@ -0,0 +1,25 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import agentsData from '@/data/documentation/agents-data.json'
import { AgentFileItem } from './AgentItems'
export function AgentsCoreServices() {
return (
<Card>
<CardHeader>
<CardTitle>Core AI Services</CardTitle>
<CardDescription>Primary modules handling AI operations</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{agentsData.coreServices.map((service) => (
<AgentFileItem
key={service.filename}
filename={service.filename}
path={service.path}
description={service.description}
features={service.features}
/>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,28 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Target, Package } from '@phosphor-icons/react'
import agentsData from '@/data/documentation/agents-data.json'
export function AgentsFutureEnhancements() {
return (
<Card className="bg-muted/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Package size={20} weight="duotone" />
Future AI Enhancements
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
{agentsData.futureEnhancements.map((item) => (
<li key={item.title} className="flex items-start gap-2">
<Target size={16} className="text-accent mt-1 flex-shrink-0" />
<span>
<strong>{item.title}:</strong> {item.description}
</span>
</li>
))}
</ul>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,21 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import agentsData from '@/data/documentation/agents-data.json'
import { IntegrationPoint } from './AgentItems'
export function AgentsIntegrationPoints() {
return (
<Card>
<CardHeader>
<CardTitle>AI Integration Points</CardTitle>
<CardDescription>Features enhanced by AI capabilities</CardDescription>
</CardHeader>
<CardContent>
<div className="grid gap-4">
{agentsData.integrationPoints.map((point) => (
<IntegrationPoint key={point.component} component={point.component} capabilities={point.capabilities} />
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,22 @@
import { Separator } from '@/components/ui/separator'
import { FileCode } from '@phosphor-icons/react'
import agentsData from '@/data/documentation/agents-data.json'
export function AgentsOverviewSection() {
return (
<div className="space-y-4">
<h1 className="text-4xl font-bold flex items-center gap-3">
<FileCode size={36} weight="duotone" className="text-accent" />
{agentsData.title}
</h1>
<p className="text-lg text-muted-foreground">{agentsData.subtitle}</p>
<Separator />
<div className="space-y-4">
<h2 className="text-2xl font-semibold">AI Service Architecture</h2>
<p className="text-foreground/90 leading-relaxed">{agentsData.overview}</p>
</div>
</div>
)
}

View File

@@ -0,0 +1,21 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import agentsData from '@/data/documentation/agents-data.json'
export function AgentsPromptEngineering() {
return (
<Card>
<CardHeader>
<CardTitle>Prompt Engineering</CardTitle>
<CardDescription>How we optimize AI interactions</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{agentsData.promptEngineering.map((item) => (
<div key={item.title} className="space-y-2">
<h3 className="font-semibold">{item.title}</h3>
<p className="text-sm text-muted-foreground">{item.description}</p>
</div>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,19 @@
import { AgentsCoreServices } from './AgentsCoreServices'
import { AgentsFutureEnhancements } from './AgentsFutureEnhancements'
import { AgentsIntegrationPoints } from './AgentsIntegrationPoints'
import { AgentsOverviewSection } from './AgentsOverviewSection'
import { AgentsPromptEngineering } from './AgentsPromptEngineering'
export function AgentsTab() {
return (
<div className="space-y-6">
<AgentsOverviewSection />
<div className="space-y-4">
<AgentsCoreServices />
<AgentsIntegrationPoints />
<AgentsPromptEngineering />
<AgentsFutureEnhancements />
</div>
</div>
)
}

View File

@@ -0,0 +1,26 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { CheckCircle, Rocket } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdBestPracticesCard() {
return (
<Card className="bg-muted/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Rocket size={20} weight="duotone" />
Best Practices
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
{cicdData.bestPractices.map((practice) => (
<li key={practice} className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>{practice}</span>
</li>
))}
</ul>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,48 @@
import { Card, CardContent } from '@/components/ui/card'
import { GitBranch } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
const toneStyles = {
green: {
card: 'bg-green-500/5 border-green-500/20',
icon: 'text-green-500'
},
blue: {
card: 'bg-blue-500/5 border-blue-500/20',
icon: 'text-blue-500'
},
purple: {
card: 'bg-purple-500/5 border-purple-500/20',
icon: 'text-purple-500'
},
orange: {
card: 'bg-orange-500/5 border-orange-500/20',
icon: 'text-orange-500'
}
} as const
export function CicdBranchStrategySection() {
return (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Branch Strategy</h2>
<div className="grid gap-4">
{cicdData.branches.map((branch) => {
const styles = toneStyles[branch.tone]
return (
<Card key={branch.name} className={styles.card}>
<CardContent className="pt-4 pb-4">
<div className="flex items-start gap-3">
<GitBranch size={20} weight="duotone" className={`${styles.icon} mt-0.5`} />
<div className="space-y-1">
<h4 className="font-semibold">{branch.name}</h4>
<p className="text-sm text-muted-foreground">{branch.description}</p>
</div>
</div>
</CardContent>
</Card>
)
})}
</div>
</div>
)
}

View File

@@ -0,0 +1,49 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { CheckCircle } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdDockerCard() {
return (
<Card>
<CardHeader>
<CardTitle>Docker Configuration</CardTitle>
<CardDescription>Containerization for production deployment</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<h3 className="font-semibold">Files Included</h3>
<div className="space-y-2 ml-4">
{cicdData.docker.files.map((file) => (
<div key={file.name} className="space-y-1">
<code className="text-sm font-mono text-accent">{file.name}</code>
<p className="text-sm text-muted-foreground">{file.description}</p>
</div>
))}
</div>
</div>
<Separator />
<div className="space-y-2">
<h3 className="font-semibold">Docker Commands</h3>
<pre className="custom-mui-code-block">{cicdData.docker.commands}</pre>
</div>
<Separator />
<div className="space-y-2">
<h3 className="font-semibold">Features</h3>
<ul className="space-y-2 text-sm">
{cicdData.docker.features.map((feature) => (
<li key={feature} className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>{feature}</span>
</li>
))}
</ul>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,39 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdEnvVarsCard() {
return (
<Card>
<CardHeader>
<CardTitle>Environment Variables</CardTitle>
<CardDescription>Required configuration for CI/CD platforms</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b">
<th className="text-left py-2 pr-4 font-semibold">Variable</th>
<th className="text-left py-2 pr-4 font-semibold">Description</th>
<th className="text-left py-2 font-semibold">Required</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
{cicdData.environmentVariables.map((variable) => (
<tr key={variable.variable} className="border-b">
<td className="py-2 pr-4">
<code className="text-accent">{variable.variable}</code>
</td>
<td className="py-2 pr-4">{variable.description}</td>
<td className="py-2">{variable.required}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,56 @@
import { Badge } from '@/components/ui/badge'
import { Card, CardContent } from '@/components/ui/card'
import { CheckCircle, GitBranch } from '@phosphor-icons/react'
export function CICDPlatformItem({ name, file, description, features }: {
name: string
file: string
description: string
features: string[]
}) {
return (
<div className="space-y-3 border-l-2 border-accent pl-4">
<div className="space-y-1">
<div className="flex items-center gap-2">
<GitBranch size={18} className="text-accent" />
<h3 className="text-base font-semibold">{name}</h3>
</div>
<code className="text-xs text-muted-foreground font-mono">{file}</code>
<p className="text-sm text-foreground/90">{description}</p>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">Key Features:</p>
<ul className="space-y-1">
{features.map((feature) => (
<li key={feature} className="text-sm text-foreground/80 flex items-start gap-2">
<CheckCircle size={14} weight="fill" className="text-accent mt-1 flex-shrink-0" />
<span>{feature}</span>
</li>
))}
</ul>
</div>
</div>
)
}
export function PipelineStageCard({ stage, description, duration }: {
stage: string
description: string
duration: string
}) {
return (
<Card className="bg-primary/5 border-primary/20">
<CardContent className="pt-4 pb-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1 flex-1">
<h4 className="font-semibold text-sm">{stage}</h4>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
<Badge variant="secondary" className="text-xs whitespace-nowrap">
{duration}
</Badge>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,26 @@
import { Separator } from '@/components/ui/separator'
import { GitBranch } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdOverviewSection() {
return (
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="w-16 h-16 rounded-xl bg-gradient-to-br from-primary to-accent flex items-center justify-center">
<GitBranch size={32} weight="duotone" className="text-white" />
</div>
<div>
<h1 className="text-4xl font-bold">{cicdData.title}</h1>
<p className="text-lg text-muted-foreground">{cicdData.subtitle}</p>
</div>
</div>
<Separator />
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Overview</h2>
<p className="text-foreground/90 leading-relaxed">{cicdData.overview}</p>
</div>
</div>
)
}

View File

@@ -0,0 +1,21 @@
import cicdData from '@/data/documentation/cicd-data.json'
import { PipelineStageCard } from './CicdItems'
export function CicdPipelineSection() {
return (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Pipeline Stages</h2>
<p className="text-foreground/90 leading-relaxed">{cicdData.pipeline.intro}</p>
<div className="grid gap-3">
{cicdData.pipeline.stages.map((stage) => (
<PipelineStageCard
key={stage.stage}
stage={stage.stage}
description={stage.description}
duration={stage.duration}
/>
))}
</div>
</div>
)
}

View File

@@ -0,0 +1,24 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import cicdData from '@/data/documentation/cicd-data.json'
import { CICDPlatformItem } from './CicdItems'
export function CicdPlatformsCard() {
return (
<Card>
<CardHeader>
<CardTitle>Available Configurations</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{cicdData.platforms.map((platform) => (
<CICDPlatformItem
key={platform.name}
name={platform.name}
file={platform.file}
description={platform.description}
features={platform.features}
/>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,31 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Lightbulb } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdQuickStartCard() {
return (
<Card className="bg-accent/10 border-accent/20">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Lightbulb size={20} weight="duotone" className="text-accent" />
Quick Start
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-3">
{cicdData.quickStart.map((step) => (
<div key={step.step} className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<span className="w-6 h-6 rounded-full bg-accent text-accent-foreground flex items-center justify-center text-sm">
{step.step}
</span>
{step.title}
</h3>
<p className="text-sm text-foreground/80 ml-8">{step.description}</p>
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,28 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { FileCode, Package } from '@phosphor-icons/react'
import cicdData from '@/data/documentation/cicd-data.json'
export function CicdResourcesCard() {
return (
<Card className="border-primary/30">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Package size={20} weight="duotone" />
Additional Resources
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
{cicdData.resources.map((resource) => (
<li key={resource.label} className="flex items-start gap-2">
<FileCode size={16} className="text-accent mt-1 flex-shrink-0" />
<span>
<code className="text-accent">{resource.label}</code> - {resource.description}
</span>
</li>
))}
</ul>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,25 @@
import { CicdBestPracticesCard } from './CicdBestPracticesCard'
import { CicdBranchStrategySection } from './CicdBranchStrategySection'
import { CicdDockerCard } from './CicdDockerCard'
import { CicdEnvVarsCard } from './CicdEnvVarsCard'
import { CicdOverviewSection } from './CicdOverviewSection'
import { CicdPipelineSection } from './CicdPipelineSection'
import { CicdPlatformsCard } from './CicdPlatformsCard'
import { CicdQuickStartCard } from './CicdQuickStartCard'
import { CicdResourcesCard } from './CicdResourcesCard'
export function CicdTab() {
return (
<div className="space-y-6">
<CicdOverviewSection />
<CicdPlatformsCard />
<CicdPipelineSection />
<CicdDockerCard />
<CicdEnvVarsCard />
<CicdBranchStrategySection />
<CicdQuickStartCard />
<CicdBestPracticesCard />
<CicdResourcesCard />
</div>
)
}

View File

@@ -0,0 +1,30 @@
import { Card, CardContent } from '@/components/ui/card'
import { Sparkle } from '@phosphor-icons/react'
export function FeatureItem({ icon, title, description }: { icon: React.ReactNode; title: string; description: string }) {
return (
<div className="flex gap-3">
<div className="text-accent mt-0.5">{icon}</div>
<div className="space-y-1">
<h4 className="font-semibold text-sm">{title}</h4>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
</div>
)
}
export function AIFeatureCard({ title, description }: { title: string; description: string }) {
return (
<Card className="bg-primary/5 border-primary/20">
<CardContent className="pt-4 pb-4">
<div className="flex gap-3">
<Sparkle size={20} weight="duotone" className="text-accent flex-shrink-0 mt-0.5" />
<div className="space-y-1">
<h4 className="font-semibold text-sm">{title}</h4>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,25 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { CheckCircle } from '@phosphor-icons/react'
import pwaData from '@/data/documentation/pwa-data.json'
export function PwaFeaturesCard() {
return (
<Card>
<CardHeader>
<CardTitle>PWA Features</CardTitle>
<CardDescription>Native app capabilities in your browser</CardDescription>
</CardHeader>
<CardContent className="grid md:grid-cols-2 gap-4">
{pwaData.features.map((feature) => (
<div key={feature.title} className="space-y-2">
<div className="flex items-center gap-2">
<CheckCircle size={16} weight="fill" className="text-accent" />
<span className="font-semibold text-sm">{feature.title}</span>
</div>
<p className="text-xs text-muted-foreground ml-6">{feature.description}</p>
</div>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,36 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import pwaData from '@/data/documentation/pwa-data.json'
function InstallationCard({ title, items }: { title: string; items: { title: string; steps: string[] }[] }) {
return (
<Card>
<CardHeader>
<CardTitle className="text-base">{title}</CardTitle>
</CardHeader>
<CardContent className="space-y-3 text-sm">
{items.map((item) => (
<div key={item.title}>
<div className="font-semibold mb-1">{item.title}</div>
<ol className="list-decimal list-inside space-y-1 text-muted-foreground ml-2">
{item.steps.map((step) => (
<li key={step}>{step}</li>
))}
</ol>
</div>
))}
</CardContent>
</Card>
)
}
export function PwaInstallationSection() {
return (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Installation</h2>
<div className="grid md:grid-cols-2 gap-4">
<InstallationCard title="Desktop Installation" items={pwaData.installation.desktop} />
<InstallationCard title="Mobile Installation" items={pwaData.installation.mobile} />
</div>
</div>
)
}

View File

@@ -0,0 +1,50 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { CheckCircle, Wrench } from '@phosphor-icons/react'
import pwaData from '@/data/documentation/pwa-data.json'
function OfflineList({ items, accent }: { items: string[]; accent: boolean }) {
return (
<ul className={`space-y-2 text-sm ${accent ? 'text-foreground/80' : 'text-muted-foreground'}`}>
{items.map((item) => (
<li key={item} className="flex items-start gap-2">
<span className={accent ? 'text-accent mt-0.5' : 'mt-0.5'}></span>
<span>{item}</span>
</li>
))}
</ul>
)
}
export function PwaOfflineSection() {
return (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Offline Capabilities</h2>
<div className="grid md:grid-cols-2 gap-4">
<Card className="border-accent/50">
<CardHeader>
<CardTitle className="text-base flex items-center gap-2">
<CheckCircle size={20} weight="fill" className="text-accent" />
Works Offline
</CardTitle>
</CardHeader>
<CardContent>
<OfflineList items={pwaData.offline.worksOffline} accent />
</CardContent>
</Card>
<Card className="border-muted">
<CardHeader>
<CardTitle className="text-base flex items-center gap-2">
<Wrench size={20} weight="duotone" className="text-muted-foreground" />
Requires Internet
</CardTitle>
</CardHeader>
<CardContent>
<OfflineList items={pwaData.offline.requiresInternet} accent={false} />
</CardContent>
</Card>
</div>
</div>
)
}

View File

@@ -0,0 +1,26 @@
import { Separator } from '@/components/ui/separator'
import { Rocket } from '@phosphor-icons/react'
import pwaData from '@/data/documentation/pwa-data.json'
export function PwaOverviewSection() {
return (
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="w-16 h-16 rounded-xl bg-gradient-to-br from-primary to-accent flex items-center justify-center">
<Rocket size={32} weight="duotone" className="text-white" />
</div>
<div>
<h1 className="text-4xl font-bold">{pwaData.title}</h1>
<p className="text-lg text-muted-foreground">{pwaData.subtitle}</p>
</div>
</div>
<Separator />
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Overview</h2>
<p className="text-foreground/90 leading-relaxed">{pwaData.overview}</p>
</div>
</div>
)
}

View File

@@ -0,0 +1,28 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Lightbulb } from '@phosphor-icons/react'
import pwaData from '@/data/documentation/pwa-data.json'
export function PwaProTipsCard() {
return (
<Card className="bg-accent/10 border-accent/20">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Lightbulb size={20} weight="duotone" className="text-accent" />
Pro Tips
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
{pwaData.proTips.map((tip) => (
<li key={tip.title} className="flex items-start gap-2">
<span className="text-accent mt-1"></span>
<span>
<strong>{tip.title}:</strong> {tip.description}
</span>
</li>
))}
</ul>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,29 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import pwaData from '@/data/documentation/pwa-data.json'
export function PwaSettingsCard() {
return (
<div className="space-y-4">
<h2 className="text-2xl font-semibold">PWA Settings</h2>
<p className="text-foreground/90 leading-relaxed">
Navigate to the <strong>PWA</strong> tab to manage all Progressive Web App features:
</p>
<Card>
<CardHeader>
<CardTitle>Available Controls</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{pwaData.settings.map((setting, index) => (
<div key={setting.title} className="space-y-2">
<div className="font-semibold">{setting.title}</div>
<p className="text-sm text-muted-foreground">{setting.description}</p>
{index < pwaData.settings.length - 1 && <Separator />}
</div>
))}
</CardContent>
</Card>
</div>
)
}

View File

@@ -0,0 +1,19 @@
import { PwaFeaturesCard } from './PwaFeaturesCard'
import { PwaInstallationSection } from './PwaInstallationSection'
import { PwaOfflineSection } from './PwaOfflineSection'
import { PwaOverviewSection } from './PwaOverviewSection'
import { PwaProTipsCard } from './PwaProTipsCard'
import { PwaSettingsCard } from './PwaSettingsCard'
export function PwaTab() {
return (
<div className="space-y-6">
<PwaOverviewSection />
<PwaFeaturesCard />
<PwaInstallationSection />
<PwaSettingsCard />
<PwaOfflineSection />
<PwaProTipsCard />
</div>
)
}

View File

@@ -0,0 +1,57 @@
import { Separator } from '@/components/ui/separator'
import { CheckCircle, Clock, MapPin } from '@phosphor-icons/react'
import roadmapData from '@/data/documentation/roadmap-data.json'
import { RoadmapItem } from './RoadmapItem'
const sections = [
{
key: 'completed',
title: 'Completed Features',
icon: <CheckCircle size={24} weight="fill" className="text-green-500" />,
items: roadmapData.completed
},
{
key: 'planned',
title: 'Planned Features',
icon: <Clock size={24} weight="duotone" className="text-accent" />,
items: roadmapData.planned
}
]
export function RoadmapTab() {
return (
<div className="space-y-6">
<div className="space-y-4">
<h1 className="text-4xl font-bold flex items-center gap-3">
<MapPin size={36} weight="duotone" className="text-accent" />
{roadmapData.title}
</h1>
<p className="text-lg text-muted-foreground">{roadmapData.subtitle}</p>
<Separator />
<div className="space-y-6">
{sections.map((section) => (
<div key={section.key}>
<div className="flex items-center gap-3 mb-4">
{section.icon}
<h2 className="text-2xl font-semibold">{section.title}</h2>
</div>
<div className="space-y-3 ml-9">
{section.items.map((item) => (
<RoadmapItem
key={`${section.key}-${item.title}`}
status={section.key === 'completed' ? 'completed' : 'planned'}
title={item.title}
description={item.description}
version={item.version}
/>
))}
</div>
</div>
))}
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,21 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import sassData from '@/data/documentation/sass-data.json'
import { AnimationItem } from './SassItems'
export function SassAnimationsCard() {
return (
<Card>
<CardHeader>
<CardTitle>Animation Classes</CardTitle>
<CardDescription>Pre-built animation utilities</CardDescription>
</CardHeader>
<CardContent>
<div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
{sassData.animations.map((animation) => (
<AnimationItem key={animation.name} name={animation.name} description={animation.description} />
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,26 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { CheckCircle, Target } from '@phosphor-icons/react'
import sassData from '@/data/documentation/sass-data.json'
export function SassBestPracticesCard() {
return (
<Card className="bg-muted/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Target size={20} weight="duotone" />
Best Practices
</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2 text-sm">
{sassData.bestPractices.map((practice) => (
<li key={practice} className="flex items-start gap-2">
<CheckCircle size={16} className="text-accent mt-1 flex-shrink-0" weight="fill" />
<span>{practice}</span>
</li>
))}
</ul>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,26 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import sassData from '@/data/documentation/sass-data.json'
import { SassComponentItem } from './SassItems'
export function SassComponentsCard() {
return (
<Card>
<CardHeader>
<CardTitle>Available Components</CardTitle>
<CardDescription>Custom Material UI components built with Sass</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid gap-4 md:grid-cols-2">
{sassData.components.map((component) => (
<SassComponentItem
key={component.name}
name={component.name}
classes={component.classes}
description={component.description}
/>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,20 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import sassData from '@/data/documentation/sass-data.json'
export function SassFileStructureCard() {
return (
<Card>
<CardHeader>
<CardTitle>File Structure</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{sassData.fileStructure.map((item) => (
<div key={item.file} className="space-y-2">
<code className="text-sm font-mono text-accent">{item.file}</code>
<p className="text-sm text-muted-foreground ml-4">{item.description}</p>
</div>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,22 @@
export function SassComponentItem({ name, classes, description }: { name: string; classes: string[]; description: string }) {
return (
<div className="space-y-2 p-4 border rounded-lg bg-card">
<h4 className="font-semibold">{name}</h4>
<p className="text-sm text-muted-foreground">{description}</p>
<div className="space-y-1">
{classes.map((cls) => (
<code key={cls} className="text-xs font-mono text-accent block">{cls}</code>
))}
</div>
</div>
)
}
export function AnimationItem({ name, description }: { name: string; description: string }) {
return (
<div className="space-y-1 p-3 border rounded-lg bg-card">
<code className="text-xs font-mono text-accent">{name}</code>
<p className="text-xs text-muted-foreground">{description}</p>
</div>
)
}

View File

@@ -0,0 +1,25 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Code } from '@phosphor-icons/react'
import sassData from '@/data/documentation/sass-data.json'
import { FeatureItem } from './FeatureItems'
export function SassLayoutCard() {
return (
<Card>
<CardHeader>
<CardTitle>Layout Components</CardTitle>
<CardDescription>Sass-powered layout utilities</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
{sassData.layoutComponents.map((item) => (
<FeatureItem
key={item.title}
icon={<Code size={18} />}
title={item.title}
description={item.description}
/>
))}
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,26 @@
import { Separator } from '@/components/ui/separator'
import { PaintBrush } from '@phosphor-icons/react'
import sassData from '@/data/documentation/sass-data.json'
export function SassOverviewSection() {
return (
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="w-16 h-16 rounded-xl bg-gradient-to-br from-primary to-accent flex items-center justify-center">
<PaintBrush size={32} weight="duotone" className="text-white" />
</div>
<div>
<h1 className="text-4xl font-bold">{sassData.title}</h1>
<p className="text-lg text-muted-foreground">{sassData.subtitle}</p>
</div>
</div>
<Separator />
<div className="space-y-4">
<h2 className="text-2xl font-semibold">Overview</h2>
<p className="text-foreground/90 leading-relaxed">{sassData.overview}</p>
</div>
</div>
)
}

View File

@@ -0,0 +1,30 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Rocket } from '@phosphor-icons/react'
import sassData from '@/data/documentation/sass-data.json'
export function SassQuickStartCard() {
return (
<Card className="bg-accent/5 border-accent/20">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Rocket size={20} weight="duotone" />
Quick Start Example
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<h3 className="font-semibold">{sassData.quickStart.components.title}</h3>
<pre className="custom-mui-code-block">{sassData.quickStart.components.code}</pre>
</div>
<Separator />
<div className="space-y-2">
<h3 className="font-semibold">{sassData.quickStart.mixins.title}</h3>
<pre className="custom-mui-code-block">{sassData.quickStart.mixins.code}</pre>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,23 @@
import { SassAnimationsCard } from './SassAnimationsCard'
import { SassBestPracticesCard } from './SassBestPracticesCard'
import { SassComponentsCard } from './SassComponentsCard'
import { SassFileStructureCard } from './SassFileStructureCard'
import { SassLayoutCard } from './SassLayoutCard'
import { SassOverviewSection } from './SassOverviewSection'
import { SassQuickStartCard } from './SassQuickStartCard'
import { SassUtilitiesCard } from './SassUtilitiesCard'
export function SassTab() {
return (
<div className="space-y-6">
<SassOverviewSection />
<SassFileStructureCard />
<SassComponentsCard />
<SassLayoutCard />
<SassUtilitiesCard />
<SassAnimationsCard />
<SassQuickStartCard />
<SassBestPracticesCard />
</div>
)
}

View File

@@ -0,0 +1,33 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Lightbulb } from '@phosphor-icons/react'
import sassData from '@/data/documentation/sass-data.json'
export function SassUtilitiesCard() {
return (
<Card>
<CardHeader>
<CardTitle>Sass Utilities & Mixins</CardTitle>
<CardDescription>Reusable functions for custom styling</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{sassData.utilities.map((utility, index) => (
<div key={utility.title} className="space-y-2">
<h3 className="font-semibold flex items-center gap-2">
<Lightbulb size={18} weight="duotone" className="text-accent" />
{utility.title}
</h3>
<div className="ml-6 space-y-2 text-sm">
<p className="font-mono text-accent">{utility.mixin}</p>
<p className="text-muted-foreground">{utility.description}</p>
<pre className="custom-mui-code-block text-xs mt-2">{utility.snippet}</pre>
</div>
{index < sassData.utilities.length - 1 && <Separator />}
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -24,10 +24,29 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import { Plus, Trash, Sparkle, Package } from '@phosphor-icons/react'
import { toast } from 'sonner'
import { FeatureIdea, IdeaGroup, IdeaEdgeData } from './FeatureIdeaCloud/types'
import { SEED_IDEAS, CATEGORIES, PRIORITIES, STATUSES, CONNECTION_STYLE, GROUP_COLORS } from './FeatureIdeaCloud/constants'
import { CONNECTION_STYLE } from './FeatureIdeaCloud/constants'
import seedIdeasData from './FeatureIdeaCloud/data/seed-ideas.json'
import categoriesData from './FeatureIdeaCloud/data/categories.json'
import prioritiesData from './FeatureIdeaCloud/data/priorities.json'
import statusesData from './FeatureIdeaCloud/data/statuses.json'
import groupColorsData from './FeatureIdeaCloud/data/group-colors.json'
import { nodeTypes } from './FeatureIdeaCloud/nodes'
import { dispatchConnectionCountUpdate } from './FeatureIdeaCloud/dispatchConnectionCountUpdate'
type SeedIdeaJson = Omit<FeatureIdea, 'createdAt'> & { createdAtOffsetMs: number }
const SEED_IDEAS: FeatureIdea[] = (seedIdeasData as SeedIdeaJson[]).map((idea) => {
const { createdAtOffsetMs, ...rest } = idea
return {
...rest,
createdAt: Date.now() - createdAtOffsetMs,
}
})
const CATEGORIES = categoriesData as string[]
const PRIORITIES = prioritiesData as FeatureIdea['priority'][]
const STATUSES = statusesData as FeatureIdea['status'][]
const GROUP_COLORS = groupColorsData as Array<{ name: string; value: string; bg: string; border: string }>
export function FeatureIdeaCloud() {
const [ideas, setIdeas] = useKV<FeatureIdea[]>('feature-ideas', SEED_IDEAS)
const [groups, setGroups] = useKV<IdeaGroup[]>('feature-idea-groups', [])

View File

@@ -1,124 +1,8 @@
import { FeatureIdea } from './types'
export const SEED_IDEAS: FeatureIdea[] = [
{
id: 'idea-1',
title: 'AI Code Assistant',
description: 'Integrate an AI assistant that can suggest code improvements and answer questions',
category: 'AI/ML',
priority: 'high',
status: 'completed',
createdAt: Date.now() - 10000000,
},
{
id: 'idea-2',
title: 'Real-time Collaboration',
description: 'Allow multiple developers to work on the same project simultaneously',
category: 'Collaboration',
priority: 'high',
status: 'idea',
createdAt: Date.now() - 9000000,
},
{
id: 'idea-3',
title: 'Component Marketplace',
description: 'A marketplace where users can share and download pre-built components',
category: 'Community',
priority: 'medium',
status: 'idea',
createdAt: Date.now() - 8000000,
},
{
id: 'idea-4',
title: 'Visual Git Integration',
description: 'Git operations through a visual interface with branch visualization',
category: 'DevOps',
priority: 'high',
status: 'planned',
createdAt: Date.now() - 7000000,
},
{
id: 'idea-5',
title: 'API Mock Server',
description: 'Built-in mock server for testing API integrations',
category: 'Testing',
priority: 'medium',
status: 'idea',
createdAt: Date.now() - 6000000,
},
{
id: 'idea-6',
title: 'Performance Profiler',
description: 'Analyze and optimize application performance with visual metrics',
category: 'Performance',
priority: 'medium',
status: 'idea',
createdAt: Date.now() - 5000000,
},
{
id: 'idea-7',
title: 'Theme Presets',
description: 'Pre-designed theme templates for quick project setup',
category: 'Design',
priority: 'low',
status: 'completed',
createdAt: Date.now() - 4000000,
},
{
id: 'idea-8',
title: 'Database Schema Migrations',
description: 'Visual tool for creating and managing database migrations',
category: 'Database',
priority: 'high',
status: 'in-progress',
createdAt: Date.now() - 3000000,
},
{
id: 'idea-9',
title: 'Mobile App Preview',
description: 'Live preview on actual mobile devices or simulators',
category: 'Mobile',
priority: 'medium',
status: 'planned',
createdAt: Date.now() - 2000000,
},
{
id: 'idea-10',
title: 'Accessibility Checker',
description: 'Automated accessibility testing and suggestions',
category: 'Accessibility',
priority: 'high',
status: 'idea',
createdAt: Date.now() - 1000000,
},
]
export const CONNECTION_STYLE = {
stroke: '#a78bfa',
strokeWidth: 2.5
}
export const CATEGORIES = [
'AI/ML',
'Collaboration',
'Community',
'DevOps',
'Testing',
'Performance',
'Design',
'Database',
'Mobile',
'Accessibility',
'Productivity',
'Security',
'Analytics',
'Other'
]
export const PRIORITIES = ['low', 'medium', 'high'] as const
export const STATUSES = ['idea', 'planned', 'in-progress', 'completed'] as const
export const STATUS_COLORS = {
idea: 'bg-muted text-muted-foreground',
planned: 'bg-accent text-accent-foreground',
@@ -131,14 +15,3 @@ export const PRIORITY_COLORS = {
medium: 'border-amber-400/60 bg-amber-50/80 dark:bg-amber-950/40',
high: 'border-red-400/60 bg-red-50/80 dark:bg-red-950/40',
}
export const GROUP_COLORS = [
{ name: 'Blue', value: '#3b82f6', bg: 'rgba(59, 130, 246, 0.08)', border: 'rgba(59, 130, 246, 0.3)' },
{ name: 'Purple', value: '#a855f7', bg: 'rgba(168, 85, 247, 0.08)', border: 'rgba(168, 85, 247, 0.3)' },
{ name: 'Green', value: '#10b981', bg: 'rgba(16, 185, 129, 0.08)', border: 'rgba(16, 185, 129, 0.3)' },
{ name: 'Red', value: '#ef4444', bg: 'rgba(239, 68, 68, 0.08)', border: 'rgba(239, 68, 68, 0.3)' },
{ name: 'Orange', value: '#f97316', bg: 'rgba(249, 115, 22, 0.08)', border: 'rgba(249, 115, 22, 0.3)' },
{ name: 'Pink', value: '#ec4899', bg: 'rgba(236, 72, 153, 0.08)', border: 'rgba(236, 72, 153, 0.3)' },
{ name: 'Cyan', value: '#06b6d4', bg: 'rgba(6, 182, 212, 0.08)', border: 'rgba(6, 182, 212, 0.3)' },
{ name: 'Amber', value: '#f59e0b', bg: 'rgba(245, 158, 11, 0.08)', border: 'rgba(245, 158, 11, 0.3)' },
]

View File

@@ -0,0 +1,16 @@
[
"AI/ML",
"Collaboration",
"Community",
"DevOps",
"Testing",
"Performance",
"Design",
"Database",
"Mobile",
"Accessibility",
"Productivity",
"Security",
"Analytics",
"Other"
]

View File

@@ -0,0 +1,10 @@
[
{ "name": "Blue", "value": "#3b82f6", "bg": "rgba(59, 130, 246, 0.08)", "border": "rgba(59, 130, 246, 0.3)" },
{ "name": "Purple", "value": "#a855f7", "bg": "rgba(168, 85, 247, 0.08)", "border": "rgba(168, 85, 247, 0.3)" },
{ "name": "Green", "value": "#10b981", "bg": "rgba(16, 185, 129, 0.08)", "border": "rgba(16, 185, 129, 0.3)" },
{ "name": "Red", "value": "#ef4444", "bg": "rgba(239, 68, 68, 0.08)", "border": "rgba(239, 68, 68, 0.3)" },
{ "name": "Orange", "value": "#f97316", "bg": "rgba(249, 115, 22, 0.08)", "border": "rgba(249, 115, 22, 0.3)" },
{ "name": "Pink", "value": "#ec4899", "bg": "rgba(236, 72, 153, 0.08)", "border": "rgba(236, 72, 153, 0.3)" },
{ "name": "Cyan", "value": "#06b6d4", "bg": "rgba(6, 182, 212, 0.08)", "border": "rgba(6, 182, 212, 0.3)" },
{ "name": "Amber", "value": "#f59e0b", "bg": "rgba(245, 158, 11, 0.08)", "border": "rgba(245, 158, 11, 0.3)" }
]

View File

@@ -0,0 +1,5 @@
[
"low",
"medium",
"high"
]

View File

@@ -0,0 +1,92 @@
[
{
"id": "idea-1",
"title": "AI Code Assistant",
"description": "Integrate an AI assistant that can suggest code improvements and answer questions",
"category": "AI/ML",
"priority": "high",
"status": "completed",
"createdAtOffsetMs": 10000000
},
{
"id": "idea-2",
"title": "Real-time Collaboration",
"description": "Allow multiple developers to work on the same project simultaneously",
"category": "Collaboration",
"priority": "high",
"status": "idea",
"createdAtOffsetMs": 9000000
},
{
"id": "idea-3",
"title": "Component Marketplace",
"description": "A marketplace where users can share and download pre-built components",
"category": "Community",
"priority": "medium",
"status": "idea",
"createdAtOffsetMs": 8000000
},
{
"id": "idea-4",
"title": "Visual Git Integration",
"description": "Git operations through a visual interface with branch visualization",
"category": "DevOps",
"priority": "high",
"status": "planned",
"createdAtOffsetMs": 7000000
},
{
"id": "idea-5",
"title": "API Mock Server",
"description": "Built-in mock server for testing API integrations",
"category": "Testing",
"priority": "medium",
"status": "idea",
"createdAtOffsetMs": 6000000
},
{
"id": "idea-6",
"title": "Performance Profiler",
"description": "Analyze and optimize application performance with visual metrics",
"category": "Performance",
"priority": "medium",
"status": "idea",
"createdAtOffsetMs": 5000000
},
{
"id": "idea-7",
"title": "Theme Presets",
"description": "Pre-designed theme templates for quick project setup",
"category": "Design",
"priority": "low",
"status": "completed",
"createdAtOffsetMs": 4000000
},
{
"id": "idea-8",
"title": "Database Schema Migrations",
"description": "Visual tool for creating and managing database migrations",
"category": "Database",
"priority": "high",
"status": "in-progress",
"createdAtOffsetMs": 3000000
},
{
"id": "idea-9",
"title": "Mobile App Preview",
"description": "Live preview on actual mobile devices or simulators",
"category": "Mobile",
"priority": "medium",
"status": "planned",
"createdAtOffsetMs": 2000000
},
{
"id": "idea-10",
"title": "Accessibility Checker",
"description": "Automated accessibility testing and suggestions",
"category": "Accessibility",
"priority": "high",
"status": "idea",
"createdAtOffsetMs": 1000000
}
]

View File

@@ -0,0 +1,6 @@
[
"idea",
"planned",
"in-progress",
"completed"
]

View File

@@ -1,5 +1,146 @@
import { GroupNode } from './GroupNode'
import { IdeaNode } from './IdeaNode'
import { useState, useEffect, ReactElement } from 'react'
import { NodeProps, Handle, Position } from 'reactflow'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { DotsThree } from '@phosphor-icons/react'
import { FeatureIdea, IdeaGroup } from './types'
import { PRIORITY_COLORS, STATUS_COLORS } from './constants'
import groupColorsData from './data/group-colors.json'
const GROUP_COLORS = groupColorsData as Array<{ name: string; value: string; bg: string; border: string }>
export function GroupNode({ data, selected }: NodeProps<IdeaGroup>) {
const colorScheme = GROUP_COLORS.find(c => c.value === data.color) || GROUP_COLORS[0]
return (
<div
className="rounded-2xl backdrop-blur-sm transition-all"
style={{
width: 450,
height: 350,
backgroundColor: colorScheme.bg,
border: `3px dashed ${colorScheme.border}`,
boxShadow: selected ? `0 0 0 2px ${colorScheme.value}` : 'none',
}}
>
<div
className="absolute -top-3 left-4 px-3 py-1 rounded-full text-xs font-semibold shadow-md"
style={{
backgroundColor: colorScheme.value,
color: 'white',
}}
>
{data.label}
</div>
<Button
size="icon"
variant="ghost"
className="absolute -top-2 -right-2 h-7 w-7 rounded-full shadow-md bg-background hover:bg-destructive hover:text-destructive-foreground"
onClick={(e) => {
e.stopPropagation()
const event = new CustomEvent('editGroup', { detail: data })
window.dispatchEvent(event)
}}
>
<DotsThree size={16} />
</Button>
</div>
)
}
export function IdeaNode({ data, selected, id }: NodeProps<FeatureIdea> & { id: string }) {
const [connectionCounts, setConnectionCounts] = useState<Record<string, number>>({
left: 0,
right: 0,
top: 0,
bottom: 0,
})
useEffect(() => {
const updateConnectionCounts = (event: CustomEvent) => {
const { nodeId, counts } = event.detail
if (nodeId === id) {
setConnectionCounts(counts)
}
}
window.addEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener)
return () => {
window.removeEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener)
}
}, [id])
const generateHandles = (position: Position, type: 'source' | 'target', side: string) => {
const count = connectionCounts[side] || 0
const totalHandles = Math.max(2, count + 1)
const handles: ReactElement[] = []
for (let i = 0; i < totalHandles; i++) {
const handleId = `${side}-${i}`
const isVertical = position === Position.Top || position === Position.Bottom
const positionStyle = isVertical
? { left: `${((i + 1) / (totalHandles + 1)) * 100}%` }
: { top: `${((i + 1) / (totalHandles + 1)) * 100}%` }
handles.push(
<Handle
key={handleId}
type={type}
position={position}
id={handleId}
className="w-3 h-3 !bg-primary border-2 border-background transition-all hover:scale-125"
style={{
...positionStyle,
transform: 'translate(-50%, -50%)',
}}
/>
)
}
return handles
}
return (
<div className="relative">
{generateHandles(Position.Left, 'target', 'left')}
{generateHandles(Position.Right, 'source', 'right')}
{generateHandles(Position.Top, 'target', 'top')}
{generateHandles(Position.Bottom, 'source', 'bottom')}
<Card className={`p-4 shadow-xl hover:shadow-2xl transition-all border-2 ${PRIORITY_COLORS[data.priority]} w-[240px] ${selected ? 'ring-2 ring-primary' : ''}`}>
<div className="space-y-2">
<div className="flex items-start justify-between gap-2">
<h3 className="font-semibold text-sm line-clamp-2 flex-1">{data.title}</h3>
<Button
size="icon"
variant="ghost"
className="h-6 w-6 shrink-0"
onClick={(e) => {
e.stopPropagation()
const event = new CustomEvent('editIdea', { detail: data })
window.dispatchEvent(event)
}}
>
<DotsThree size={16} />
</Button>
</div>
<p className="text-xs text-muted-foreground line-clamp-2">
{data.description}
</p>
<div className="flex flex-wrap gap-1">
<Badge variant="secondary" className="text-xs">
{data.category}
</Badge>
<Badge className={`text-xs ${STATUS_COLORS[data.status]}`}>
{data.status}
</Badge>
</div>
</div>
</Card>
</div>
)
}
export const nodeTypes = {
ideaNode: IdeaNode,

View File

@@ -1,4 +1,6 @@
{
"title": "Agents Files",
"subtitle": "AI agent configuration and service architecture",
"overview": "CodeForge uses a modular AI service architecture that integrates OpenAI's GPT models across all features. Each designer has specialized prompts and validation logic to ensure high-quality generated code.",
"coreServices": [
{

View File

@@ -53,62 +53,66 @@
]
}
],
"pipelineStages": [
{
"stage": "Lint",
"description": "ESLint and TypeScript type checking to ensure code quality",
"duration": "~1-2 min"
},
{
"stage": "Test",
"description": "Unit tests with coverage reporting and result artifacts",
"duration": "~2-3 min"
},
{
"stage": "Build",
"description": "Production build with artifact generation for deployment",
"duration": "~2-4 min"
},
{
"stage": "E2E Tests",
"description": "Playwright end-to-end tests with HTML reports",
"duration": "~3-5 min"
},
{
"stage": "Security",
"description": "npm audit and Trivy vulnerability scanning",
"duration": "~1-2 min"
},
{
"stage": "Docker Build",
"description": "Multi-stage Docker image build and push to registry",
"duration": "~3-5 min"
},
{
"stage": "Deploy",
"description": "Automated deployment to staging and production environments",
"duration": "~1-3 min"
}
],
"dockerConfig": {
"pipeline": {
"intro": "All CI/CD configurations follow a similar multi-stage pipeline structure:",
"stages": [
{
"stage": "Lint",
"description": "ESLint and TypeScript type checking to ensure code quality",
"duration": "~1-2 min"
},
{
"stage": "Test",
"description": "Unit tests with coverage reporting and result artifacts",
"duration": "~2-3 min"
},
{
"stage": "Build",
"description": "Production build with artifact generation for deployment",
"duration": "~2-4 min"
},
{
"stage": "E2E Tests",
"description": "Playwright end-to-end tests with HTML reports",
"duration": "~3-5 min"
},
{
"stage": "Security",
"description": "npm audit and Trivy vulnerability scanning",
"duration": "~1-2 min"
},
{
"stage": "Docker Build",
"description": "Multi-stage Docker image build and push to registry",
"duration": "~3-5 min"
},
{
"stage": "Deploy",
"description": "Automated deployment to staging and production environments",
"duration": "~1-3 min"
}
]
},
"docker": {
"files": [
{
"file": "Dockerfile",
"name": "Dockerfile",
"description": "Multi-stage build with Node.js builder and Nginx runtime"
},
{
"file": "nginx.conf",
"name": "nginx.conf",
"description": "Production Nginx configuration with health checks and caching"
},
{
"file": "docker-compose.yml",
"name": "docker-compose.yml",
"description": "Local development and deployment orchestration"
},
{
"file": ".dockerignore",
"name": ".dockerignore",
"description": "Optimized build context by excluding unnecessary files"
}
],
"commands": "# Build image locally\ndocker build -t codeforge:local .\n\n# Run container\ndocker run -p 3000:80 codeforge:local\n\n# Use docker-compose\ndocker-compose up -d\n\n# Pull from registry\ndocker pull ghcr.io/<username>/<repo>:latest",
"features": [
"Multi-stage build reduces final image size to ~50MB",
"Nginx serves static files with gzip compression",
@@ -121,54 +125,54 @@
{
"variable": "NODE_VERSION",
"description": "Node.js version (default: 20)",
"required": false
"required": "No"
},
{
"variable": "REGISTRY",
"description": "Docker registry URL (default: ghcr.io)",
"required": false
"required": "No"
},
{
"variable": "STAGING_WEBHOOK_URL",
"description": "Webhook for staging deployments",
"required": false
"required": "Optional"
},
{
"variable": "PRODUCTION_WEBHOOK_URL",
"description": "Webhook for production deployments",
"required": false
"required": "Optional"
},
{
"variable": "CODECOV_TOKEN",
"description": "Codecov integration token",
"required": false
"required": "Optional"
},
{
"variable": "SLACK_WEBHOOK",
"description": "Slack webhook for notifications",
"required": false
"required": "Optional"
}
],
"branchStrategy": [
"branches": [
{
"branch": "main",
"name": "main",
"description": "Production branch - deploys to production environment (manual approval required)",
"color": "green"
"tone": "green"
},
{
"branch": "develop",
"name": "develop",
"description": "Development branch - automatically deploys to staging environment",
"color": "blue"
"tone": "blue"
},
{
"branch": "feature/*",
"name": "feature/*",
"description": "Feature branches - runs tests only, no deployment",
"color": "purple"
"tone": "purple"
},
{
"branch": "v* tags",
"name": "v* tags",
"description": "Version tags - triggers release workflow with artifacts and changelog",
"color": "orange"
"tone": "orange"
}
],
"quickStart": [
@@ -203,25 +207,25 @@
"Use semantic versioning for releases (v1.0.0, v1.1.0, etc.)",
"Configure Slack or email notifications for deployment status"
],
"additionalResources": [
"resources": [
{
"file": "CI_CD_GUIDE.md",
"label": "CI_CD_GUIDE.md",
"description": "Detailed setup guide for all platforms"
},
{
"file": ".github/workflows/",
"label": ".github/workflows/",
"description": "GitHub Actions workflows"
},
{
"file": ".gitlab-ci.yml",
"label": ".gitlab-ci.yml",
"description": "GitLab CI configuration"
},
{
"file": "Jenkinsfile",
"label": "Jenkinsfile",
"description": "Jenkins pipeline definition"
},
{
"file": ".circleci/config.yml",
"label": ".circleci/config.yml",
"description": "CircleCI configuration"
}
]

View File

@@ -31,7 +31,7 @@
"installation": {
"desktop": [
{
"platform": "Chrome/Edge/Brave",
"title": "Chrome/Edge/Brave:",
"steps": [
"Look for install icon (⊕) in address bar",
"Click \"Install\" or use prompt in app",
@@ -39,7 +39,7 @@
]
},
{
"platform": "Safari (macOS)",
"title": "Safari (macOS):",
"steps": [
"Click File → Add to Dock",
"App appears in Dock"
@@ -48,15 +48,15 @@
],
"mobile": [
{
"platform": "iOS (Safari)",
"title": "iOS (Safari):",
"steps": [
"Tap Share button",
"Select \"Add to Home Screen\"",
"Confirm installation"
"Tap \"Add\""
]
},
{
"platform": "Android (Chrome)",
"title": "Android (Chrome):",
"steps": [
"Tap menu (three dots)",
"Select \"Install app\"",
@@ -87,7 +87,7 @@
"description": "Install pending updates when new versions are available"
}
],
"offlineCapabilities": {
"offline": {
"worksOffline": [
"View and edit existing projects",
"Browse files and code",

View File

@@ -1,4 +1,6 @@
{
"title": "Product Roadmap",
"subtitle": "Features delivered and planned for CodeForge development",
"completed": [
{
"title": "Monaco Code Editor Integration",

View File

@@ -27,7 +27,13 @@
"components": [
{
"name": "Buttons",
"classes": ["mui-custom-button--primary", "mui-custom-button--secondary", "mui-custom-button--accent", "mui-custom-button--outline", "mui-custom-button--ghost"],
"classes": [
"mui-custom-button--primary",
"mui-custom-button--secondary",
"mui-custom-button--accent",
"mui-custom-button--outline",
"mui-custom-button--ghost"
],
"description": "Custom styled buttons with hover effects and variants"
},
{
@@ -78,56 +84,62 @@
],
"layoutComponents": [
{
"name": "custom-mui-container",
"title": "custom-mui-container",
"description": "Max-width container with responsive padding"
},
{
"name": "custom-mui-grid",
"title": "custom-mui-grid",
"description": "CSS Grid layouts with responsive columns (--cols-1 to --cols-12, --responsive)"
},
{
"name": "custom-mui-flex",
"title": "custom-mui-flex",
"description": "Flexbox utilities (--row, --col, --wrap, --center, --between, --around)"
},
{
"name": "custom-mui-stack",
"title": "custom-mui-stack",
"description": "Vertical/horizontal stacks with configurable gaps"
},
{
"name": "custom-mui-surface",
"title": "custom-mui-surface",
"description": "Interactive surfaces with elevation and hover effects"
}
],
"utilities": [
{
"name": "@include respond-to($breakpoint)",
"title": "Responsive Design",
"mixin": "@include respond-to($breakpoint)",
"description": "Generate media queries for xs, sm, md, lg, xl, 2xl breakpoints",
"example": "@include respond-to('lg') {\n padding: 2rem;\n}"
"snippet": "@include respond-to('lg') {\n padding: 2rem;\n}"
},
{
"name": "@include elevation($level)",
"title": "Elevation & Shadows",
"mixin": "@include elevation($level)",
"description": "Apply box shadows with levels 1-4",
"example": "@include elevation(2);"
"snippet": "@include elevation(2);"
},
{
"name": "@include glassmorphism($blur, $opacity)",
"title": "Glassmorphism",
"mixin": "@include glassmorphism($blur, $opacity)",
"description": "Create frosted glass effects with backdrop blur",
"example": "@include glassmorphism(16px, 0.1);"
"snippet": "@include glassmorphism(16px, 0.1);"
},
{
"name": "get-color($palette, $shade)",
"title": "Color Functions",
"mixin": "get-color($palette, $shade)",
"description": "Access colors from predefined palettes (primary, secondary, accent, success, error, warning)",
"example": "color: get-color('primary', 500);"
"snippet": "color: get-color('primary', 500);"
},
{
"name": "@include truncate($lines)",
"title": "Text Truncation",
"mixin": "@include truncate($lines)",
"description": "Truncate text with ellipsis after specified lines",
"example": "@include truncate(2);"
"snippet": "@include truncate(2);"
},
{
"name": "@include show-scrollbar($track, $thumb)",
"title": "Custom Scrollbars",
"mixin": "@include show-scrollbar($track, $thumb)",
"description": "Style webkit scrollbars with custom colors",
"example": "@include show-scrollbar(rgba(0,0,0,0.1), rgba(0,0,0,0.3));"
"snippet": "@include show-scrollbar(rgba(0,0,0,0.1), rgba(0,0,0,0.3));"
}
],
"animations": [
@@ -142,6 +154,16 @@
{ "name": "animate-float", "description": "Floating up and down" },
{ "name": "animate-glow", "description": "Glowing shadow effect" }
],
"quickStart": {
"components": {
"title": "Using Custom Components",
"code": "import './styles/main.scss'\n\nfunction MyComponent() {\n return (\n <div className=\"custom-mui-container\">\n <div className=\"custom-mui-grid custom-mui-grid--cols-3\">\n <div className=\"mui-custom-card\">\n <h3>Card Title</h3>\n <p>Card content</p>\n <button className=\"mui-custom-button mui-custom-button--primary\">\n Click Me\n </button>\n </div>\n </div>\n </div>\n )\n}"
},
"mixins": {
"title": "Creating Custom Styles with Mixins",
"code": "@use './styles/utilities' as *;\n@use './styles/variables' as *;\n\n.my-custom-component {\n @include elevation(2);\n @include responsive-padding(spacing('6'));\n background: get-color('primary', 500);\n \n @include respond-to('md') {\n @include elevation(3);\n }\n \n &:hover {\n @include glassmorphism(12px, 0.15);\n }\n}"
}
},
"bestPractices": [
"Import main.scss in your index.css to access all Sass components and utilities",
"Use @use instead of @import for better module encapsulation",