diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/billing/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/billing/page.tsx deleted file mode 100644 index 787c8be..0000000 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/billing/page.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { Suspense } from 'react'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"; -import { Loader2, CreditCard, ArrowRight, ShieldCheck, Zap } from "lucide-react"; - -export default async function BillingPage(props: { params: Promise<{ projectId: string }> }) { - const { projectId } = await props.params; - - return ( -
-
-

- Payments & Billing -

-

- Connect your bank account to start charging customers for this project. -

-
- -
- - {/* Onboarding Card */} - - -
-
- -
-
- Accept Payments with Stripe - Setup takes 3 minutes. Vibn handles the code. -
-
-
- -
-

What you get immediately:

-
    -
  • - - AI Auto-Wiring: The Vibn AI will automatically inject your secure Stripe keys into your live Coolify application. -
  • -
  • - - Instant Compliance: Securely accept Apple Pay, Google Pay, and credit cards with PCI compliance handled automatically. -
  • -
-
- -

- By connecting, you agree to Stripe's Services Agreement. Vibn takes a small 1% platform fee on successful transactions to keep the AI platform running. -

-
- - - -
- -
-
- ); -} diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/product/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/code/page.tsx similarity index 99% rename from vibn-frontend/app/[workspace]/project/[projectId]/(home)/product/page.tsx rename to vibn-frontend/app/[workspace]/project/[projectId]/(home)/code/page.tsx index b1f2cc1..90c82a2 100644 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/product/page.tsx +++ b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/code/page.tsx @@ -28,7 +28,7 @@ type Selection = | { type: "image"; uuid: string } | null; -export default function ProductTab() { +export default function CodeTab() { const params = useParams(); const projectId = params.projectId as string; const { anatomy, loading, error } = useAnatomy(projectId); diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/market/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/market/page.tsx deleted file mode 100644 index b6fb9e0..0000000 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/market/page.tsx +++ /dev/null @@ -1,351 +0,0 @@ -import { BigQuery } from '@google-cloud/bigquery'; -import { Suspense } from 'react'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { Loader2, Users, Target, Search, Database } from "lucide-react"; - -async function getMarketData(projectId: string) { - let bqOptions: any = { projectId: process.env.GCP_PROJECT_ID || 'master-ai-484822' }; - if (process.env.GOOGLE_SERVICE_ACCOUNT_KEY_B64) { - try { - const saStr = Buffer.from(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_B64, 'base64').toString('utf8'); - bqOptions.credentials = JSON.parse(saStr); - bqOptions.projectId = bqOptions.credentials.project_id; - } catch (e) {} - } - const bigquery = new BigQuery(bqOptions); - - try { - const [leads] = await bigquery.query({ - query: `SELECT * FROM \`master-ai-484822.vibn_market_data.market_leads\` WHERE project_id = @projectId OR project_id = 'SYSTEM_BACKFILL' LIMIT 50`, - params: { projectId } - }); - - const [aggregations] = await bigquery.query({ - query: `SELECT * FROM \`master-ai-484822.vibn_market_data.market_aggregations\` ORDER BY last_updated DESC LIMIT 1` - }); - - const [competitors] = await bigquery.query({ - query: `SELECT * FROM \`master-ai-484822.vibn_market_data.software_providers_seo\` ORDER BY last_updated DESC LIMIT 10` - }); - - return { leads, aggregations: aggregations[0], competitors }; - } catch (err) { - console.error("BigQuery Error:", err); - return { leads: [], aggregations: null, competitors: [] }; - } -} - -export default async function MarketPage(props: { params: Promise<{ projectId: string }> }) { - const { projectId } = await props.params; - - return ( -
-
-

- Market Intelligence -

-

- Real-time TAM, verified leads, and competitor teardowns from the Vibn Data Co-op. -

-
- -
}> - - - - ); -} - -async function MarketDataDisplay({ projectId }: { projectId: string }) { - const data = await getMarketData(projectId); - - if (!data.aggregations && data.leads.length === 0) { - return ( - - - -

No Market Data Yet

-

- Ask the Vibn AI to run market research for your niche to populate this dashboard with leads, competitors, and SEO insights. -

-
-
- ); - } - - return ( -
- {/* Overview Cards */} -
- - - - Total Addressable Market - - - -
- {data.aggregations?.total_market_size?.toLocaleString() || "..."} -
-

Verified businesses in selected region

-
-
- - - - - Qualified Leads Captured - - - -
- {data.leads.length} -
-

Ready for cold outreach

-
-
- - - - - Tech Debt Indicator - - - -
- {data.aggregations ? Math.round((data.aggregations.websites_count / data.aggregations.total_market_size) * 100) : 0}% -
-

Of TAM have a website

-
-
-
- -
- {/* Pain Points */} - {data.aggregations && ( - - - Customer Pain Points - Extracted from Google Reviews - - -
- {Object.entries(typeof data.aggregations.customer_pain_points === 'string' ? JSON.parse(data.aggregations.customer_pain_points) : data.aggregations.customer_pain_points || {}) - .sort(([, a], [, b]) => (b as number) - (a as number)) - .slice(0, 15) - .map(([topic, count]) => ( - - {topic} ({(count as number).toLocaleString()}) - - ))} -
-
-
- )} - - {/* Sub-niches */} - {data.aggregations && ( - - - Market Sub-Niches - Breakdown of primary category - - -
- {Object.entries(typeof data.aggregations.sub_niches === 'string' ? JSON.parse(data.aggregations.sub_niches) : data.aggregations.sub_niches || {}) - .sort(([, a], [, b]) => (b as number) - (a as number)) - .slice(0, 6) - .map(([topic, count]) => ( -
- {topic.replace(/_/g, ' ')} - {(count as number).toLocaleString()} -
- ))} -
-
-
- )} -
- - {/* Competitors */} - {data.competitors.length > 0 && ( - - - SaaS Competitors & Ad Spend - Top incumbents and their Google Ads budget - -
- - - - - - - - - - - {data.competitors.map((comp: any) => { - const paidKw = typeof comp.top_paid_keywords === 'string' ? JSON.parse(comp.top_paid_keywords) : comp.top_paid_keywords; - return ( - - - - - - - ); - })} - -
DomainMonthly Ad SpendOrganic TrafficTop Paid Keywords
{comp.domain} - ${Math.round(comp.ad_spend_usd).toLocaleString()} - - {Math.round(comp.organic_traffic).toLocaleString()} /mo - -
- {(paidKw || []).slice(0, 3).map((kw: string) => ( - - {kw} - - ))} -
-
-
-
- )} - - {/* Leads Table */} - {data.leads.length > 0 && ( - - - Verified Leads - First {data.leads.length} contacts matching your target market - -
- - - - - - - - - - - {data.leads.map((lead: any) => { - const emails = typeof lead.emails === 'string' ? JSON.parse(lead.emails) : lead.emails; - return ( - - - - - - - ); - })} - -
Business NameLocationRatingContact
- {lead.name} - {lead.website && ( - - {lead.website.replace(/^https?:\/\//, '')} - - )} - - {lead.city}, {lead.region} - - {lead.rating ? `${lead.rating} ⭐ (${lead.reviews_count})` : 'N/A'} - -
- {lead.phone &&
{lead.phone}
} - {(emails || []).map((e: string) => ( - - {e} - - ))} -
-
-
-
- )} - - {/* ───────────────────────────────────────────────────────────── */} - {/* GO-TO-MARKET (GTM) STRATEGY ENGINE */} - {/* ───────────────────────────────────────────────────────────── */} -
-
-
-

- Go-To-Market Strategy -

-

- Synthesize market data into an actionable marketing and positioning plan. -

-
- -
- -
- - - Brand Positioning - Value prop, target persona, and wedge strategy. - - -
-

Generate a plan to reveal the positioning strategy.

-
-
-
- - - - SEO & Content Engine - Keyword gaps and initial blog architecture. - - -
-

Generate a plan to reveal keyword targets.

-
-
-
-
- -
- - - - Social Media Automation - POWERED BY MISSINGLETTR - - A 3-month automated drip campaign based on your positioning. - - -
-

Generate a plan to automatically orchestrate your social media strategy via Missinglettr.

-
-
-
-
-
-
- ); -} diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/hosting/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/overview/page.tsx similarity index 99% rename from vibn-frontend/app/[workspace]/project/[projectId]/(home)/hosting/page.tsx rename to vibn-frontend/app/[workspace]/project/[projectId]/(home)/overview/page.tsx index 919d631..126d5cb 100644 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/hosting/page.tsx +++ b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/overview/page.tsx @@ -44,7 +44,7 @@ type Preview = Anatomy["hosting"]["previews"][number]; // Main component // ────────────────────────────────────────────────── -export default function HostingTab() { +export default function OverviewTab() { const params = useParams(); const projectId = params.projectId as string; const { anatomy, loading, error } = useAnatomy(projectId, { pollMs: 8000 }); diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/plan/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/plan/page.tsx index 43941b9..094b446 100644 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/plan/page.tsx +++ b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/plan/page.tsx @@ -121,7 +121,7 @@ export default function PlanTab() {
} selectedId={selectedId} onClick={setSelectedId} @@ -282,7 +282,7 @@ function ObjectivePanel({
-

Project Objective

+

Product Brief

The high-level business case and elevator pitch.

diff --git a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/infrastructure/page.tsx b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/security/page.tsx similarity index 99% rename from vibn-frontend/app/[workspace]/project/[projectId]/(home)/infrastructure/page.tsx rename to vibn-frontend/app/[workspace]/project/[projectId]/(home)/security/page.tsx index 3479c77..d20453e 100644 --- a/vibn-frontend/app/[workspace]/project/[projectId]/(home)/infrastructure/page.tsx +++ b/vibn-frontend/app/[workspace]/project/[projectId]/(home)/security/page.tsx @@ -112,7 +112,7 @@ function categoryDef(key: CategoryKey): CategoryDef { return CATEGORIES.find(c => c.key === key)!; } -export default function InfrastructureTab() { +export default function SecurityTab() { const params = useParams(); const projectId = params.projectId as string; const { anatomy, loading, error } = useAnatomy(projectId); diff --git a/vibn-frontend/components/project/dashboard-sidebar.tsx b/vibn-frontend/components/project/dashboard-sidebar.tsx index a80efbb..78cf945 100644 --- a/vibn-frontend/components/project/dashboard-sidebar.tsx +++ b/vibn-frontend/components/project/dashboard-sidebar.tsx @@ -6,18 +6,14 @@ import { usePathname } from "next/navigation"; import { Search, LayoutGrid, - Users, + ClipboardList, Database, BarChart2, - TrendingUp, Globe, Plug, ShieldCheck, Code2, - Bot, - Zap, Terminal, - FileJson, Settings, ChevronDown, ChevronRight, @@ -56,29 +52,19 @@ export function DashboardSidebar({ const menuItems = [ { segment: "overview", label: "Overview", Icon: LayoutGrid }, - { segment: "users", label: "Users", Icon: Users }, + { segment: "plan", label: "Plan & Specs", Icon: ClipboardList }, + { segment: "data", label: "Data", Icon: Database }, { - segment: "data", - label: "Data", - Icon: Database, - hasChildren: true, - }, - { segment: "analytics", label: "Analytics", Icon: BarChart2 }, - { - segment: "marketing", - label: "Marketing", - Icon: TrendingUp, - badge: "New", - hasChildren: true, + segment: "analytics", + label: "Analytics", + Icon: BarChart2, + badge: "Soon", }, { segment: "domains", label: "Domains", Icon: Globe }, { segment: "integrations", label: "Integrations", Icon: Plug }, { segment: "security", label: "Security", Icon: ShieldCheck }, { segment: "code", label: "Code", Icon: Code2 }, - { segment: "agents", label: "Agents", Icon: Bot, badge: "New" }, - { segment: "automations", label: "Automations", Icon: Zap }, { segment: "logs", label: "Logs", Icon: Terminal }, - { segment: "api", label: "API", Icon: FileJson }, { segment: "settings", label: "Settings", @@ -87,7 +73,6 @@ export function DashboardSidebar({ children: [ { segment: "settings/app", label: "App Settings" }, { segment: "settings/auth", label: "Authentication" }, - { segment: "settings/template", label: "App Template" }, ], }, ];