- Created KPIDashboard component with tab navigation (product/acquisition/revenue/report) - Created MixpanelPanel for product KPIs linking to Mixpanel - Created GA4Panel for acquisition KPIs linking to GA4 - Created StripePanel for revenue KPIs linking to Stripe dashboard - Created UnifiedReport with KPI thresholds table and reporting schedule - Added KPI dashboard route (/app/kpi) and sidebar navigation link - Added KPI dashboard CSS styles (metric cards, tabs, table, info cards) - Fixed pre-existing parse errors in Faq.tsx (unescaped apostrophes) - Fixed pre-existing CSS import paths in routes.tsx Co-Authored-By: Paperclip <noreply@paperclip.ing>
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { Component, createSignal, Show } from 'solid-js';
|
|
import { A } from '@solidjs/router';
|
|
import { useAuth, useAuthActions } from '../../lib/auth';
|
|
|
|
export const AppLayout: Component<any> = (props) => {
|
|
const auth = useAuth();
|
|
const { signOut } = useAuthActions();
|
|
const [sidebarOpen, setSidebarOpen] = createSignal(true);
|
|
|
|
return (
|
|
<div class="freno-layout">
|
|
<aside class="freno-sidebar" classList={{ 'freno-sidebar-collapsed': !sidebarOpen() }}>
|
|
<div class="freno-sidebar-header">
|
|
<div class="freno-logo">
|
|
<span class="freno-logo-icon">F</span>
|
|
<span class="freno-logo-text">FrenoCorp</span>
|
|
</div>
|
|
<button class="freno-sidebar-toggle" onClick={() => setSidebarOpen(!sidebarOpen())}>
|
|
{sidebarOpen() ? '◀' : '▶'}
|
|
</button>
|
|
</div>
|
|
|
|
<nav class="freno-sidebar-nav">
|
|
<A href="/dashboard" class="freno-nav-link" end>
|
|
<span class="freno-nav-icon">📊</span>
|
|
<span class="freno-nav-text">Dashboard</span>
|
|
</A>
|
|
<A href="/kpi" class="freno-nav-link">
|
|
<span class="freno-nav-icon">📈</span>
|
|
<span class="freno-nav-text">KPIs</span>
|
|
</A>
|
|
<A href="/projects" class="freno-nav-link">
|
|
<span class="freno-nav-icon">📁</span>
|
|
<span class="freno-nav-text">Projects</span>
|
|
</A>
|
|
<A href="/teams" class="freno-nav-link">
|
|
<span class="freno-nav-icon">👥</span>
|
|
<span class="freno-nav-text">Teams</span>
|
|
</A>
|
|
</nav>
|
|
|
|
<div class="freno-sidebar-footer">
|
|
<div class="freno-user-menu">
|
|
<A href="/profile" class="freno-user-link">
|
|
<div class="freno-avatar">
|
|
{auth().user?.name?.charAt(0)?.toUpperCase() || 'U'}
|
|
</div>
|
|
<div class="freno-user-info">
|
|
<div class="freno-user-name">{auth().user?.name || 'User'}</div>
|
|
<div class="freno-user-email">{auth().user?.email}</div>
|
|
</div>
|
|
</A>
|
|
<button class="freno-btn-icon" onClick={signOut} title="Sign out">
|
|
⏻
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<main class="freno-main">
|
|
<header class="freno-header">
|
|
<button class="freno-mobile-menu" onClick={() => setSidebarOpen(!sidebarOpen())}>
|
|
☰
|
|
</button>
|
|
<div class="freno-header-content">
|
|
<h2 class="freno-page-title">{getPageTitle()}</h2>
|
|
</div>
|
|
<div class="freno-header-actions">
|
|
<button class="freno-btn-icon" title="Notifications">🔔</button>
|
|
<button class="freno-btn-icon" title="Settings">⚙</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="freno-content">
|
|
{props.children}
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
function getPageTitle(): string {
|
|
const path = window.location.pathname;
|
|
const titles: Record<string, string> = {
|
|
'/dashboard': 'Dashboard',
|
|
'/kpi': 'KPI Dashboard',
|
|
'/projects': 'Projects',
|
|
'/projects/new': 'New Project',
|
|
'/profile': 'Profile',
|
|
'/teams': 'Teams',
|
|
};
|
|
return titles[path] || 'FrenoCorp';
|
|
}
|