@sdvf23rvfa43f/sidebar-header 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ComponentType, ReactNode } from 'react';
3
+
4
+ interface PlaceholderPageProps {
5
+ title: string;
6
+ subtitle?: string;
7
+ icon?: ComponentType<{
8
+ className?: string;
9
+ }>;
10
+ badge?: string;
11
+ children?: ReactNode;
12
+ }
13
+ declare function PlaceholderPage({ title, subtitle, icon: Icon, badge, children, }: PlaceholderPageProps): react_jsx_runtime.JSX.Element;
14
+
15
+ export { PlaceholderPage as P, type PlaceholderPageProps as a };
@@ -0,0 +1,183 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { LayoutDashboard, Server, Shield, AppWindow, Layers, HardDrive, Zap, Globe, Network, Receipt, LifeBuoy, TicketPlus, Users, Rocket } from 'lucide-react';
3
+ import { useLocation } from 'react-router';
4
+
5
+ // src/pages/PlaceholderPage.tsx
6
+ function PlaceholderPage({
7
+ title,
8
+ subtitle,
9
+ icon: Icon,
10
+ badge,
11
+ children
12
+ }) {
13
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 px-6 py-20", children: [
14
+ Icon && /* @__PURE__ */ jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/[0.04] ring-1 ring-white/[0.06]", children: /* @__PURE__ */ jsx(Icon, { className: "h-8 w-8 text-sg-text-muted" }) }),
15
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
16
+ /* @__PURE__ */ jsx("h1", { className: "text-sg-text-primary text-2xl font-semibold", children: title }),
17
+ badge && /* @__PURE__ */ jsx("span", { className: "rounded-md bg-white/[0.06] px-2 py-0.5 text-xs text-sg-text-muted ring-1 ring-white/[0.08]", children: badge })
18
+ ] }),
19
+ subtitle && /* @__PURE__ */ jsx("p", { className: "max-w-md text-center text-sg-text-muted", children: subtitle }),
20
+ children
21
+ ] });
22
+ }
23
+ function DashboardPage() {
24
+ return /* @__PURE__ */ jsx(
25
+ PlaceholderPage,
26
+ {
27
+ title: "Dashboard",
28
+ subtitle: "Overview of your Caasify infrastructure and services.",
29
+ icon: LayoutDashboard
30
+ }
31
+ );
32
+ }
33
+ function ServersPage() {
34
+ return /* @__PURE__ */ jsx(
35
+ PlaceholderPage,
36
+ {
37
+ title: "Servers",
38
+ subtitle: "Manage your Cloud VPS instances.",
39
+ icon: Server
40
+ }
41
+ );
42
+ }
43
+ function VpnPage() {
44
+ return /* @__PURE__ */ jsx(
45
+ PlaceholderPage,
46
+ {
47
+ title: "VPNs",
48
+ subtitle: "Manage your VPN connections and tunnels.",
49
+ icon: Shield
50
+ }
51
+ );
52
+ }
53
+ function ApplicationPage() {
54
+ return /* @__PURE__ */ jsx(
55
+ PlaceholderPage,
56
+ {
57
+ title: "Application",
58
+ subtitle: "Deploy and manage your applications.",
59
+ icon: AppWindow,
60
+ badge: "SOON"
61
+ }
62
+ );
63
+ }
64
+ function PlatformPage() {
65
+ return /* @__PURE__ */ jsx(
66
+ PlaceholderPage,
67
+ {
68
+ title: "Platform",
69
+ subtitle: "Manage your platform infrastructure and services.",
70
+ icon: Layers,
71
+ badge: "SOON"
72
+ }
73
+ );
74
+ }
75
+ function S3Page() {
76
+ return /* @__PURE__ */ jsx(
77
+ PlaceholderPage,
78
+ {
79
+ title: "S3",
80
+ subtitle: "Object storage buckets and file management.",
81
+ icon: HardDrive,
82
+ badge: "SOON"
83
+ }
84
+ );
85
+ }
86
+ function FunctionsPage() {
87
+ return /* @__PURE__ */ jsx(
88
+ PlaceholderPage,
89
+ {
90
+ title: "Functions",
91
+ subtitle: "Deploy and manage serverless functions.",
92
+ icon: Zap,
93
+ badge: "BETA"
94
+ }
95
+ );
96
+ }
97
+ function DomainPage() {
98
+ return /* @__PURE__ */ jsx(
99
+ PlaceholderPage,
100
+ {
101
+ title: "Domain",
102
+ subtitle: "Register and manage your domain names.",
103
+ icon: Globe,
104
+ badge: "BETA"
105
+ }
106
+ );
107
+ }
108
+ function DnsServicePage() {
109
+ return /* @__PURE__ */ jsx(
110
+ PlaceholderPage,
111
+ {
112
+ title: "DNS Service",
113
+ subtitle: "Configure DNS zones and records.",
114
+ icon: Network,
115
+ badge: "BETA"
116
+ }
117
+ );
118
+ }
119
+ function BillingPage() {
120
+ return /* @__PURE__ */ jsx(
121
+ PlaceholderPage,
122
+ {
123
+ title: "View Invoices",
124
+ subtitle: "Review your billing history and manage payment methods.",
125
+ icon: Receipt
126
+ }
127
+ );
128
+ }
129
+ function SupportPage() {
130
+ return /* @__PURE__ */ jsx(
131
+ PlaceholderPage,
132
+ {
133
+ title: "Support",
134
+ subtitle: "Browse help articles and view your support tickets.",
135
+ icon: LifeBuoy
136
+ }
137
+ );
138
+ }
139
+ function OpenTicketPage() {
140
+ return /* @__PURE__ */ jsx(
141
+ PlaceholderPage,
142
+ {
143
+ title: "Open Ticket",
144
+ subtitle: "Create a new support ticket and get help from our team.",
145
+ icon: TicketPlus
146
+ }
147
+ );
148
+ }
149
+ function BecomeResellerPage() {
150
+ return /* @__PURE__ */ jsx(
151
+ PlaceholderPage,
152
+ {
153
+ title: "Become Reseller",
154
+ subtitle: "Join the Caasify reseller program and grow your business.",
155
+ icon: Users
156
+ }
157
+ );
158
+ }
159
+ function OrderServicePage() {
160
+ return /* @__PURE__ */ jsx(
161
+ PlaceholderPage,
162
+ {
163
+ title: "Deploy",
164
+ subtitle: "Choose a service and deploy in seconds.",
165
+ icon: Rocket
166
+ }
167
+ );
168
+ }
169
+ function NotFoundPage() {
170
+ const location = useLocation();
171
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 px-6 py-20", children: [
172
+ /* @__PURE__ */ jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/[0.04] ring-1 ring-white/[0.06]", children: /* @__PURE__ */ jsx("span", { className: "text-2xl", children: "404" }) }),
173
+ /* @__PURE__ */ jsx("h1", { className: "text-sg-text-primary text-2xl font-semibold", children: "Page Not Found" }),
174
+ /* @__PURE__ */ jsxs("p", { className: "max-w-md text-center text-sg-text-muted", children: [
175
+ "No route matches ",
176
+ /* @__PURE__ */ jsx("code", { className: "rounded bg-white/[0.06] px-1.5 py-0.5 text-sm", children: location.pathname })
177
+ ] })
178
+ ] });
179
+ }
180
+
181
+ export { ApplicationPage, BecomeResellerPage, BillingPage, DashboardPage, DnsServicePage, DomainPage, FunctionsPage, NotFoundPage, OpenTicketPage, OrderServicePage, PlaceholderPage, PlatformPage, S3Page, ServersPage, SupportPage, VpnPage };
182
+ //# sourceMappingURL=chunk-JNP6BURZ.js.map
183
+ //# sourceMappingURL=chunk-JNP6BURZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/PlaceholderPage.tsx","../src/pages/DashboardPage.tsx","../src/pages/ServersPage.tsx","../src/pages/VpnPage.tsx","../src/pages/ApplicationPage.tsx","../src/pages/PlatformPage.tsx","../src/pages/S3Page.tsx","../src/pages/FunctionsPage.tsx","../src/pages/DomainPage.tsx","../src/pages/DnsServicePage.tsx","../src/pages/BillingPage.tsx","../src/pages/SupportPage.tsx","../src/pages/OpenTicketPage.tsx","../src/pages/BecomeResellerPage.tsx","../src/pages/OrderServicePage.tsx","../src/pages/NotFoundPage.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-JNP6BURZ.js","sourcesContent":["/* ═══════════════════════════════════════════════════════════════\n PlaceholderPage — Generic stub page for routes not yet implemented\n ═══════════════════════════════════════════════════════════════ */\n\nimport type { ComponentType, ReactNode } from 'react';\n\nexport interface PlaceholderPageProps {\n title: string;\n subtitle?: string;\n icon?: ComponentType<{ className?: string }>;\n badge?: string;\n children?: ReactNode;\n}\n\nexport function PlaceholderPage({\n title,\n subtitle,\n icon: Icon,\n badge,\n children,\n}: PlaceholderPageProps) {\n return (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-4 px-6 py-20\">\n {Icon && (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-white/[0.04] ring-1 ring-white/[0.06]\">\n <Icon className=\"h-8 w-8 text-sg-text-muted\" />\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <h1 className=\"text-sg-text-primary text-2xl font-semibold\">{title}</h1>\n {badge && (\n <span className=\"rounded-md bg-white/[0.06] px-2 py-0.5 text-xs text-sg-text-muted ring-1 ring-white/[0.08]\">\n {badge}\n </span>\n )}\n </div>\n {subtitle && (\n <p className=\"max-w-md text-center text-sg-text-muted\">{subtitle}</p>\n )}\n {children}\n </div>\n );\n}\n","import { LayoutDashboard } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function DashboardPage() {\n return (\n <PlaceholderPage\n title=\"Dashboard\"\n subtitle=\"Overview of your Caasify infrastructure and services.\"\n icon={LayoutDashboard}\n />\n );\n}\n","import { Server } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function ServersPage() {\n return (\n <PlaceholderPage\n title=\"Servers\"\n subtitle=\"Manage your Cloud VPS instances.\"\n icon={Server}\n />\n );\n}\n","import { Shield } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function VpnPage() {\n return (\n <PlaceholderPage\n title=\"VPNs\"\n subtitle=\"Manage your VPN connections and tunnels.\"\n icon={Shield}\n />\n );\n}\n","import { AppWindow } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function ApplicationPage() {\n return (\n <PlaceholderPage\n title=\"Application\"\n subtitle=\"Deploy and manage your applications.\"\n icon={AppWindow}\n badge=\"SOON\"\n />\n );\n}\n","import { Layers } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function PlatformPage() {\n return (\n <PlaceholderPage\n title=\"Platform\"\n subtitle=\"Manage your platform infrastructure and services.\"\n icon={Layers}\n badge=\"SOON\"\n />\n );\n}\n","import { HardDrive } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function S3Page() {\n return (\n <PlaceholderPage\n title=\"S3\"\n subtitle=\"Object storage buckets and file management.\"\n icon={HardDrive}\n badge=\"SOON\"\n />\n );\n}\n","import { Zap } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function FunctionsPage() {\n return (\n <PlaceholderPage\n title=\"Functions\"\n subtitle=\"Deploy and manage serverless functions.\"\n icon={Zap}\n badge=\"BETA\"\n />\n );\n}\n","import { Globe } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function DomainPage() {\n return (\n <PlaceholderPage\n title=\"Domain\"\n subtitle=\"Register and manage your domain names.\"\n icon={Globe}\n badge=\"BETA\"\n />\n );\n}\n","import { Network } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function DnsServicePage() {\n return (\n <PlaceholderPage\n title=\"DNS Service\"\n subtitle=\"Configure DNS zones and records.\"\n icon={Network}\n badge=\"BETA\"\n />\n );\n}\n","import { Receipt } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function BillingPage() {\n return (\n <PlaceholderPage\n title=\"View Invoices\"\n subtitle=\"Review your billing history and manage payment methods.\"\n icon={Receipt}\n />\n );\n}\n","import { LifeBuoy } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function SupportPage() {\n return (\n <PlaceholderPage\n title=\"Support\"\n subtitle=\"Browse help articles and view your support tickets.\"\n icon={LifeBuoy}\n />\n );\n}\n","import { TicketPlus } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function OpenTicketPage() {\n return (\n <PlaceholderPage\n title=\"Open Ticket\"\n subtitle=\"Create a new support ticket and get help from our team.\"\n icon={TicketPlus}\n />\n );\n}\n","import { Users } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function BecomeResellerPage() {\n return (\n <PlaceholderPage\n title=\"Become Reseller\"\n subtitle=\"Join the Caasify reseller program and grow your business.\"\n icon={Users}\n />\n );\n}\n","import { Rocket } from 'lucide-react';\nimport { PlaceholderPage } from './PlaceholderPage';\n\nexport function OrderServicePage() {\n return (\n <PlaceholderPage\n title=\"Deploy\"\n subtitle=\"Choose a service and deploy in seconds.\"\n icon={Rocket}\n />\n );\n}\n","import { useLocation } from 'react-router';\n\nexport function NotFoundPage() {\n const location = useLocation();\n return (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-4 px-6 py-20\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-white/[0.04] ring-1 ring-white/[0.06]\">\n <span className=\"text-2xl\">404</span>\n </div>\n <h1 className=\"text-sg-text-primary text-2xl font-semibold\">Page Not Found</h1>\n <p className=\"max-w-md text-center text-sg-text-muted\">\n No route matches <code className=\"rounded bg-white/[0.06] px-1.5 py-0.5 text-sm\">{location.pathname}</code>\n </p>\n </div>\n );\n}\n"]}
@@ -0,0 +1,179 @@
1
+ import { resolveCurrentId, caasifyRouteMap, caasifyNavigation, caasifyHeaderCTA, CAASIFY_WALLET_CURRENCY, caasifyLogo } from './chunk-PZYJ3H4D.js';
2
+ import { NotFoundPage, OrderServicePage, BecomeResellerPage, OpenTicketPage, SupportPage, BillingPage, DnsServicePage, DomainPage, FunctionsPage, S3Page, PlatformPage, ApplicationPage, VpnPage, ServersPage, DashboardPage } from './chunk-JNP6BURZ.js';
3
+ import { useLocation, useNavigate, createBrowserRouter, Outlet } from 'react-router';
4
+ import { AppShell } from '@sdvf23rvfa43f/stealth-glass';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ function CaasifyShell({
8
+ children,
9
+ isAuthenticated,
10
+ user,
11
+ onSignOut,
12
+ walletBalance,
13
+ walletCurrency = CAASIFY_WALLET_CURRENCY,
14
+ onAddFunds,
15
+ navigation = caasifyNavigation,
16
+ routeMap = caasifyRouteMap,
17
+ headerLeftSlot,
18
+ headerRightSlot,
19
+ ambientColors,
20
+ contentMaxWidth,
21
+ isLoading,
22
+ footerSlot,
23
+ contextualNav
24
+ }) {
25
+ const location = useLocation();
26
+ const navigate = useNavigate();
27
+ const currentId = resolveCurrentId(location.pathname);
28
+ const contextual = contextualNav ? contextualNav(currentId) : null;
29
+ const effectiveRouteMap = contextual ? { ...routeMap, ...contextual.routeMap } : routeMap;
30
+ const effectiveNavigation = contextual ? navigation.length > 0 ? [navigation[0], contextual.section, ...navigation.slice(1)] : [contextual.section] : navigation;
31
+ let effectiveCurrentId = currentId;
32
+ if (contextual) {
33
+ let longestMatch = 0;
34
+ const scanItem = (itemId) => {
35
+ const path = effectiveRouteMap[itemId];
36
+ if (path && path !== "/" && location.pathname.startsWith(path) && path.length > longestMatch) {
37
+ longestMatch = path.length;
38
+ effectiveCurrentId = itemId;
39
+ }
40
+ };
41
+ for (const item of contextual.section.items) {
42
+ scanItem(item.id);
43
+ if (item.children) {
44
+ for (const child of item.children) {
45
+ scanItem(child.id);
46
+ }
47
+ }
48
+ }
49
+ }
50
+ const handleNavigate = (id) => {
51
+ const path = effectiveRouteMap[id];
52
+ if (path) navigate(path);
53
+ };
54
+ const wallet = walletBalance !== void 0 ? {
55
+ balance: walletBalance,
56
+ currency: walletCurrency,
57
+ onAddFunds: onAddFunds ?? (() => navigate("/billing"))
58
+ } : void 0;
59
+ const ctaButton = {
60
+ label: caasifyHeaderCTA.label,
61
+ icon: caasifyHeaderCTA.icon,
62
+ onClick: () => navigate(caasifyHeaderCTA.route)
63
+ };
64
+ return /* @__PURE__ */ jsx(
65
+ AppShell,
66
+ {
67
+ logo: caasifyLogo,
68
+ navigation: effectiveNavigation,
69
+ currentId: effectiveCurrentId,
70
+ onNavigate: handleNavigate,
71
+ isAuthenticated,
72
+ user,
73
+ onSignOut: onSignOut ?? (() => {
74
+ }),
75
+ wallet,
76
+ ctaButton,
77
+ headerLeftSlot,
78
+ headerRightSlot,
79
+ ambientColors,
80
+ contentMaxWidth,
81
+ isLoading,
82
+ footerSlot,
83
+ children
84
+ }
85
+ );
86
+ }
87
+ var ROUTE_IDS = {
88
+ ROOT: "root",
89
+ DASHBOARD: "dashboard",
90
+ SERVERS: "cloud-vps",
91
+ VPN: "vpn",
92
+ APPLICATION: "app",
93
+ PLATFORM: "platform",
94
+ S3: "s3",
95
+ FUNCTIONS: "serverless",
96
+ DOMAIN: "domain",
97
+ DNS_SERVICE: "route53",
98
+ BILLING: "billing",
99
+ SUPPORT: "support",
100
+ OPEN_TICKET: "support-open-ticket",
101
+ BECOME_RESELLER: "become-reseller",
102
+ ORDER_SERVICE: "order-service",
103
+ NOT_FOUND: "not-found"
104
+ };
105
+ var defaultPageMap = {
106
+ [ROUTE_IDS.DASHBOARD]: DashboardPage,
107
+ [ROUTE_IDS.SERVERS]: ServersPage,
108
+ [ROUTE_IDS.VPN]: VpnPage,
109
+ [ROUTE_IDS.APPLICATION]: ApplicationPage,
110
+ [ROUTE_IDS.PLATFORM]: PlatformPage,
111
+ [ROUTE_IDS.S3]: S3Page,
112
+ [ROUTE_IDS.FUNCTIONS]: FunctionsPage,
113
+ [ROUTE_IDS.DOMAIN]: DomainPage,
114
+ [ROUTE_IDS.DNS_SERVICE]: DnsServicePage,
115
+ [ROUTE_IDS.BILLING]: BillingPage,
116
+ [ROUTE_IDS.SUPPORT]: SupportPage,
117
+ [ROUTE_IDS.OPEN_TICKET]: OpenTicketPage,
118
+ [ROUTE_IDS.BECOME_RESELLER]: BecomeResellerPage,
119
+ [ROUTE_IDS.ORDER_SERVICE]: OrderServicePage,
120
+ [ROUTE_IDS.NOT_FOUND]: NotFoundPage
121
+ };
122
+ function buildChildRoutes(pageOverrides = {}, extraRoutes = []) {
123
+ const page = (id) => pageOverrides[id] ?? defaultPageMap[id] ?? NotFoundPage;
124
+ return [
125
+ // ── Overview ───────────────────────────────────
126
+ { id: ROUTE_IDS.DASHBOARD, index: true, Component: page(ROUTE_IDS.DASHBOARD) },
127
+ { id: ROUTE_IDS.SERVERS, path: "cloud-vps", Component: page(ROUTE_IDS.SERVERS) },
128
+ { id: ROUTE_IDS.VPN, path: "vpn", Component: page(ROUTE_IDS.VPN) },
129
+ { id: ROUTE_IDS.APPLICATION, path: "app", Component: page(ROUTE_IDS.APPLICATION) },
130
+ { id: ROUTE_IDS.PLATFORM, path: "platform", Component: page(ROUTE_IDS.PLATFORM) },
131
+ { id: ROUTE_IDS.S3, path: "s3", Component: page(ROUTE_IDS.S3) },
132
+ { id: ROUTE_IDS.FUNCTIONS, path: "serverless", Component: page(ROUTE_IDS.FUNCTIONS) },
133
+ { id: ROUTE_IDS.DOMAIN, path: "domain", Component: page(ROUTE_IDS.DOMAIN) },
134
+ { id: ROUTE_IDS.DNS_SERVICE, path: "route53", Component: page(ROUTE_IDS.DNS_SERVICE) },
135
+ // ── Account ───────────────────────────────────
136
+ { id: ROUTE_IDS.BILLING, path: "billing", Component: page(ROUTE_IDS.BILLING) },
137
+ { id: ROUTE_IDS.SUPPORT, path: "support", Component: page(ROUTE_IDS.SUPPORT) },
138
+ { id: ROUTE_IDS.OPEN_TICKET, path: "support/open-ticket", Component: page(ROUTE_IDS.OPEN_TICKET) },
139
+ { id: ROUTE_IDS.BECOME_RESELLER, path: "become-reseller", Component: page(ROUTE_IDS.BECOME_RESELLER) },
140
+ // ── Header CTA ────────────────────────────────
141
+ { id: ROUTE_IDS.ORDER_SERVICE, path: "order-service", Component: page(ROUTE_IDS.ORDER_SERVICE) },
142
+ // ── Extra routes from consumer ────────────────
143
+ ...extraRoutes,
144
+ // ── Catch-all 404 ─────────────────────────────
145
+ { id: ROUTE_IDS.NOT_FOUND, path: "*", Component: page(ROUTE_IDS.NOT_FOUND) }
146
+ ];
147
+ }
148
+ function createRootComponent(shellProps) {
149
+ const { children: _ignored, isAuthenticated, ...rest } = shellProps;
150
+ return function CaasifyRoot() {
151
+ return /* @__PURE__ */ jsx(CaasifyShell, { ...rest, isAuthenticated: isAuthenticated ?? false, children: /* @__PURE__ */ jsx(Outlet, {}) });
152
+ };
153
+ }
154
+ function buildCaasifyRoutes(options = {}) {
155
+ const {
156
+ shellProps = {},
157
+ pageOverrides = {},
158
+ extraRoutes = [],
159
+ topLevelRoutes = [],
160
+ RootComponent
161
+ } = options;
162
+ const Root = RootComponent ?? createRootComponent(shellProps);
163
+ return [
164
+ {
165
+ id: ROUTE_IDS.ROOT,
166
+ path: "/",
167
+ Component: Root,
168
+ children: buildChildRoutes(pageOverrides, extraRoutes)
169
+ },
170
+ ...topLevelRoutes
171
+ ];
172
+ }
173
+ function createCaasifyRouter(options = {}) {
174
+ return createBrowserRouter(buildCaasifyRoutes(options));
175
+ }
176
+
177
+ export { CaasifyShell, ROUTE_IDS, buildCaasifyRoutes, buildChildRoutes, createCaasifyRouter, defaultPageMap };
178
+ //# sourceMappingURL=chunk-PJ3VQ2RZ.js.map
179
+ //# sourceMappingURL=chunk-PJ3VQ2RZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/CaasifyShell.tsx","../src/routes.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-PJ3VQ2RZ.js","sourcesContent":["/* ═══════════════════════════════════════════════════════════════\n @sdvf23rvfa43f/sidebar-header — CaasifyShell Component\n ═══════════════════════════════════════════════════════════════\n Pre-wired AppShell with Caasify navigation.\n Drop into any micro-project's root route:\n \n import { CaasifyShell } from '@sdvf23rvfa43f/sidebar-header';\n \n export default function Root() {\n return (\n <CaasifyShell\n isAuthenticated={true}\n user={{ name: 'Jane', email: 'jane@acme.io' }}\n walletBalance={124.50}\n onSignOut={() => auth.signOut()}\n >\n <Outlet />\n </CaasifyShell>\n );\n }\n ═══════════════════════════════════════════════════════════════ */\n\nimport { type ReactNode } from 'react';\nimport { useLocation, useNavigate } from 'react-router';\nimport { AppShell } from '@sdvf23rvfa43f/stealth-glass';\nimport type { SidebarUser, AppShellProps, SidebarNavItem } from '@sdvf23rvfa43f/stealth-glass';\n\n/** Nav item that may have inline children (used by contextual nav). */\ntype NavItemWithChildren = SidebarNavItem & { children?: SidebarNavItem[] };\n\nimport {\n caasifyLogo,\n caasifyNavigation,\n caasifyRouteMap,\n caasifyHeaderCTA,\n resolveCurrentId,\n CAASIFY_WALLET_CURRENCY,\n} from './navigation';\nimport type { ContextualNav } from './navigation';\n\n// ─── Props ───────────────────────────────────────────────────\n\nexport interface CaasifyShellProps {\n children: ReactNode;\n\n /** Auth state */\n isAuthenticated: boolean;\n user?: SidebarUser;\n onSignOut?: () => void;\n\n /** Wallet balance (shown in sidebar). Omit to hide wallet widget. */\n walletBalance?: number;\n /** Wallet currency symbol. Default: '€' */\n walletCurrency?: string;\n /** Callback when \"Add Funds\" is clicked. Defaults to navigate('/billing'). */\n onAddFunds?: () => void;\n\n /** Override navigation sections (advanced). Default: Caasify canonical nav. */\n navigation?: AppShellProps['navigation'];\n /** Override route map (advanced). Default: caasifyRouteMap. */\n routeMap?: Record<string, string>;\n\n /** Extra AppShell props forwarded directly (headerLeftSlot, ambientColors, etc.) */\n headerLeftSlot?: AppShellProps['headerLeftSlot'];\n headerRightSlot?: AppShellProps['headerRightSlot'];\n ambientColors?: AppShellProps['ambientColors'];\n contentMaxWidth?: AppShellProps['contentMaxWidth'];\n isLoading?: AppShellProps['isLoading'];\n footerSlot?: AppShellProps['footerSlot'];\n\n /**\n * Contextual sidebar section resolver (Option B).\n * Called with the resolved canonical `currentId` on every render.\n * Return a `ContextualNav` to inject a dynamic section between Overview and Account,\n * or `null` to show the default 2-section layout.\n *\n * The resolver should be pure and cheap. Memoize with `useCallback` if needed.\n */\n contextualNav?: (currentId: string) => ContextualNav | null;\n}\n\n// ─── Component ───────────────────────────────────────────────\n\nexport function CaasifyShell({\n children,\n isAuthenticated,\n user,\n onSignOut,\n walletBalance,\n walletCurrency = CAASIFY_WALLET_CURRENCY,\n onAddFunds,\n navigation = caasifyNavigation,\n routeMap = caasifyRouteMap,\n headerLeftSlot,\n headerRightSlot,\n ambientColors,\n contentMaxWidth,\n isLoading,\n footerSlot,\n contextualNav,\n}: CaasifyShellProps) {\n const location = useLocation();\n const navigate = useNavigate();\n const currentId = resolveCurrentId(location.pathname);\n\n // ── Contextual section resolution ────────────────────────\n // Use consumer resolver if provided, otherwise no contextual nav\n const contextual = contextualNav ? contextualNav(currentId) : null;\n\n // Merge route maps: contextual entries layered on top of canonical\n const effectiveRouteMap = contextual\n ? { ...routeMap, ...contextual.routeMap }\n : routeMap;\n\n // Splice contextual section between Overview (idx 0) and Account (idx 1+)\n const effectiveNavigation = contextual\n ? navigation.length > 0\n ? [navigation[0], contextual.section, ...navigation.slice(1)]\n : [contextual.section]\n : navigation;\n\n // Resolve contextual active item via longest pathname prefix match\n // Priority: contextual item > canonical currentId\n // Scans both top-level items AND inline children\n let effectiveCurrentId = currentId;\n if (contextual) {\n let longestMatch = 0;\n const scanItem = (itemId: string) => {\n const path = effectiveRouteMap[itemId];\n if (\n path &&\n path !== '/' &&\n location.pathname.startsWith(path) &&\n path.length > longestMatch\n ) {\n longestMatch = path.length;\n effectiveCurrentId = itemId;\n }\n };\n for (const item of contextual.section.items as NavItemWithChildren[]) {\n scanItem(item.id);\n // Also scan inline children\n if (item.children) {\n for (const child of item.children) {\n scanItem(child.id);\n }\n }\n }\n }\n\n const handleNavigate = (id: string) => {\n const path = effectiveRouteMap[id];\n if (path) navigate(path);\n };\n\n const wallet = walletBalance !== undefined\n ? {\n balance: walletBalance,\n currency: walletCurrency,\n onAddFunds: onAddFunds ?? (() => navigate('/billing')),\n }\n : undefined;\n\n const ctaButton = {\n label: caasifyHeaderCTA.label,\n icon: caasifyHeaderCTA.icon,\n onClick: () => navigate(caasifyHeaderCTA.route),\n };\n\n return (\n <AppShell\n logo={caasifyLogo}\n navigation={effectiveNavigation}\n currentId={effectiveCurrentId}\n onNavigate={handleNavigate}\n isAuthenticated={isAuthenticated}\n user={user}\n onSignOut={onSignOut ?? (() => {})}\n wallet={wallet}\n ctaButton={ctaButton}\n headerLeftSlot={headerLeftSlot}\n headerRightSlot={headerRightSlot}\n ambientColors={ambientColors}\n contentMaxWidth={contentMaxWidth}\n isLoading={isLoading}\n footerSlot={footerSlot}\n >\n {children}\n </AppShell>\n );\n}","/* ═══════════════════════════════════════════════════════════════\n @sdvf23rvfa43f/sidebar-header — Route Definitions & Router Factory\n ═══════════════════════════════════════════════════════════════\n \n Two usage modes:\n \n A) Full router (zero-config):\n import { createCaasifyRouter } from '@sdvf23rvfa43f/sidebar-header/routes';\n const router = createCaasifyRouter();\n <RouterProvider router={router} />\n \n B) Route objects only (mix with your own routes):\n import { caasifyRoutes, caasifyChildRoutes } from '@sdvf23rvfa43f/sidebar-header/routes';\n const router = createBrowserRouter([\n ...caasifyRoutes,\n { path: '/my-custom', Component: MyPage },\n ]);\n \n ═══════════════════════════════════════════════════════════════ */\n\nimport type { ComponentType } from 'react';\nimport { createBrowserRouter, Outlet } from 'react-router';\nimport type { RouteObject } from 'react-router';\n\nimport { CaasifyShell } from './CaasifyShell';\nimport type { CaasifyShellProps } from './CaasifyShell';\n\n// Default placeholder pages\nimport {\n DashboardPage,\n ServersPage,\n VpnPage,\n ApplicationPage,\n PlatformPage,\n S3Page,\n FunctionsPage,\n DomainPage,\n DnsServicePage,\n BillingPage,\n SupportPage,\n OpenTicketPage,\n BecomeResellerPage,\n OrderServicePage,\n NotFoundPage,\n} from './pages';\n\n// ─── Route ID constants ──────────────────────────────────────\n\nexport const ROUTE_IDS = {\n ROOT: 'root',\n DASHBOARD: 'dashboard',\n SERVERS: 'cloud-vps',\n VPN: 'vpn',\n APPLICATION: 'app',\n PLATFORM: 'platform',\n S3: 's3',\n FUNCTIONS: 'serverless',\n DOMAIN: 'domain',\n DNS_SERVICE: 'route53',\n BILLING: 'billing',\n SUPPORT: 'support',\n OPEN_TICKET: 'support-open-ticket',\n BECOME_RESELLER: 'become-reseller',\n ORDER_SERVICE: 'order-service',\n NOT_FOUND: 'not-found',\n} as const;\n\n// ─── Route-to-component default map ──────────────────────────\n\n/** Default page component for each route. Override via `pageOverrides`. */\nexport const defaultPageMap: Record<string, ComponentType> = {\n [ROUTE_IDS.DASHBOARD]: DashboardPage,\n [ROUTE_IDS.SERVERS]: ServersPage,\n [ROUTE_IDS.VPN]: VpnPage,\n [ROUTE_IDS.APPLICATION]: ApplicationPage,\n [ROUTE_IDS.PLATFORM]: PlatformPage,\n [ROUTE_IDS.S3]: S3Page,\n [ROUTE_IDS.FUNCTIONS]: FunctionsPage,\n [ROUTE_IDS.DOMAIN]: DomainPage,\n [ROUTE_IDS.DNS_SERVICE]: DnsServicePage,\n [ROUTE_IDS.BILLING]: BillingPage,\n [ROUTE_IDS.SUPPORT]: SupportPage,\n [ROUTE_IDS.OPEN_TICKET]: OpenTicketPage,\n [ROUTE_IDS.BECOME_RESELLER]: BecomeResellerPage,\n [ROUTE_IDS.ORDER_SERVICE]: OrderServicePage,\n [ROUTE_IDS.NOT_FOUND]: NotFoundPage,\n};\n\n// ─── Child route definitions ─────────────────────────────────\n\n/**\n * Canonical child routes for the Caasify shell.\n * Each route uses a default placeholder page that can be overridden.\n */\nexport function buildChildRoutes(\n pageOverrides: Partial<Record<string, ComponentType>> = {},\n extraRoutes: RouteObject[] = [],\n): RouteObject[] {\n const page = (id: string): ComponentType =>\n pageOverrides[id] ?? defaultPageMap[id] ?? NotFoundPage;\n\n return [\n // ── Overview ───────────────────────────────────\n { id: ROUTE_IDS.DASHBOARD, index: true, Component: page(ROUTE_IDS.DASHBOARD) },\n { id: ROUTE_IDS.SERVERS, path: 'cloud-vps', Component: page(ROUTE_IDS.SERVERS) },\n { id: ROUTE_IDS.VPN, path: 'vpn', Component: page(ROUTE_IDS.VPN) },\n { id: ROUTE_IDS.APPLICATION, path: 'app', Component: page(ROUTE_IDS.APPLICATION) },\n { id: ROUTE_IDS.PLATFORM, path: 'platform', Component: page(ROUTE_IDS.PLATFORM) },\n { id: ROUTE_IDS.S3, path: 's3', Component: page(ROUTE_IDS.S3) },\n { id: ROUTE_IDS.FUNCTIONS, path: 'serverless', Component: page(ROUTE_IDS.FUNCTIONS) },\n { id: ROUTE_IDS.DOMAIN, path: 'domain', Component: page(ROUTE_IDS.DOMAIN) },\n { id: ROUTE_IDS.DNS_SERVICE, path: 'route53', Component: page(ROUTE_IDS.DNS_SERVICE) },\n\n // ── Account ───────────────────────────────────\n { id: ROUTE_IDS.BILLING, path: 'billing', Component: page(ROUTE_IDS.BILLING) },\n { id: ROUTE_IDS.SUPPORT, path: 'support', Component: page(ROUTE_IDS.SUPPORT) },\n { id: ROUTE_IDS.OPEN_TICKET, path: 'support/open-ticket', Component: page(ROUTE_IDS.OPEN_TICKET) },\n { id: ROUTE_IDS.BECOME_RESELLER, path: 'become-reseller', Component: page(ROUTE_IDS.BECOME_RESELLER) },\n\n // ── Header CTA ────────────────────────────────\n { id: ROUTE_IDS.ORDER_SERVICE, path: 'order-service', Component: page(ROUTE_IDS.ORDER_SERVICE) },\n\n // ── Extra routes from consumer ────────────────\n ...extraRoutes,\n\n // ── Catch-all 404 ─────────────────────────────\n { id: ROUTE_IDS.NOT_FOUND, path: '*', Component: page(ROUTE_IDS.NOT_FOUND) },\n ];\n}\n\n// ─── Root layout wrapper factory ─────────────────────────────\n\nfunction createRootComponent(shellProps: Partial<CaasifyShellProps>) {\n // `children` is managed internally (Outlet), `isAuthenticated` gets a safe default.\n // Everything else (navigation, routeMap, contextualNav, wallet*, header slots, etc.)\n // flows through `...rest` into CaasifyShell unchanged.\n const { children: _ignored, isAuthenticated, ...rest } = shellProps as CaasifyShellProps;\n\n return function CaasifyRoot() {\n return (\n <CaasifyShell {...rest} isAuthenticated={isAuthenticated ?? false}>\n <Outlet />\n </CaasifyShell>\n );\n };\n}\n\n// ─── Full route tree ─────────────────────────────────────────\n\nexport interface CaasifyRouterOptions {\n /** Props forwarded to CaasifyShell (auth, user, wallet, etc.) */\n shellProps?: Partial<CaasifyShellProps>;\n\n /** Override specific page components by route ID. */\n pageOverrides?: Partial<Record<string, ComponentType>>;\n\n /** Extra child routes appended inside the shell layout. */\n extraRoutes?: RouteObject[];\n\n /** Extra top-level routes added OUTSIDE the shell (e.g. /login). */\n topLevelRoutes?: RouteObject[];\n\n /** Custom root component. If provided, shellProps is ignored. */\n RootComponent?: ComponentType;\n}\n\n/**\n * Build the full Caasify route array (not yet a router).\n * Use this if you want to combine with your own `createBrowserRouter` call.\n */\nexport function buildCaasifyRoutes(options: CaasifyRouterOptions = {}): RouteObject[] {\n const {\n shellProps = {},\n pageOverrides = {},\n extraRoutes = [],\n topLevelRoutes = [],\n RootComponent,\n } = options;\n\n const Root = RootComponent ?? createRootComponent(shellProps);\n\n return [\n {\n id: ROUTE_IDS.ROOT,\n path: '/',\n Component: Root,\n children: buildChildRoutes(pageOverrides, extraRoutes),\n },\n ...topLevelRoutes,\n ];\n}\n\n/**\n * One-liner: creates a complete `BrowserRouter` with the Caasify shell + all routes.\n *\n * ```tsx\n * import { createCaasifyRouter } from '@sdvf23rvfa43f/sidebar-header/routes';\n * const router = createCaasifyRouter({ shellProps: { isAuthenticated: true } });\n * <RouterProvider router={router} />\n * ```\n */\nexport function createCaasifyRouter(options: CaasifyRouterOptions = {}) {\n return createBrowserRouter(buildCaasifyRoutes(options));\n}"]}
@@ -0,0 +1,68 @@
1
+ import { ShoppingCart, LayoutDashboard, Server, Shield, AppWindow, Layers, HardDrive, Zap, Globe, Network, Receipt, LifeBuoy, TicketPlus, Users } from 'lucide-react';
2
+
3
+ // src/navigation.ts
4
+ var caasifyLogo = {
5
+ src: "https://upload.caasify.com/logo/logo-70x70.png",
6
+ alt: "Caasify",
7
+ title: "Caasify"
8
+ };
9
+ var caasifyNavigation = [
10
+ {
11
+ category: "Overview",
12
+ items: [
13
+ { id: "dashboard", label: "Dashboard", icon: LayoutDashboard },
14
+ { id: "cloud-vps", label: "Servers", icon: Server },
15
+ { id: "vpn", label: "VPNs", icon: Shield },
16
+ { id: "app", label: "Application", icon: AppWindow, badge: "SOON" },
17
+ { id: "platform", label: "Platform", icon: Layers, badge: "SOON" },
18
+ { id: "s3", label: "S3", icon: HardDrive, badge: "SOON" },
19
+ { id: "serverless", label: "Functions", icon: Zap, badge: "BETA" },
20
+ { id: "domain", label: "Domain", icon: Globe, badge: "BETA" },
21
+ { id: "route53", label: "DNS Service", icon: Network, badge: "BETA" }
22
+ ]
23
+ },
24
+ {
25
+ category: "Account",
26
+ items: [
27
+ { id: "billing", label: "View Invoices", icon: Receipt },
28
+ { id: "support", label: "Support", icon: LifeBuoy },
29
+ { id: "support-open-ticket", label: "Open Ticket", icon: TicketPlus },
30
+ { id: "become-reseller", label: "Become Reseller", icon: Users }
31
+ ]
32
+ }
33
+ ];
34
+ var caasifyRouteMap = {
35
+ "dashboard": "/",
36
+ "cloud-vps": "/cloud-vps",
37
+ "vpn": "/vpn",
38
+ "app": "/app",
39
+ "platform": "/platform",
40
+ "s3": "/s3",
41
+ "serverless": "/serverless",
42
+ "domain": "/domain",
43
+ "route53": "/route53",
44
+ "billing": "/billing",
45
+ "support": "/support",
46
+ "support-open-ticket": "/support/open-ticket",
47
+ "become-reseller": "/become-reseller",
48
+ "order-service": "/order-service"
49
+ };
50
+ var caasifyPathToId = Object.fromEntries(
51
+ Object.entries(caasifyRouteMap).map(([id, path]) => [path, id])
52
+ );
53
+ var caasifyHeaderCTA = {
54
+ label: "Create Order",
55
+ icon: ShoppingCart,
56
+ route: "/order-service"
57
+ };
58
+ var CAASIFY_WALLET_CURRENCY = "\u20AC";
59
+ function resolveCurrentId(pathname) {
60
+ if (caasifyPathToId[pathname]) return caasifyPathToId[pathname];
61
+ const match = Object.entries(caasifyRouteMap).filter(([, path]) => path !== "/" && pathname.startsWith(path)).sort((a, b) => b[1].length - a[1].length)[0];
62
+ return match?.[0] ?? "dashboard";
63
+ }
64
+ var CAASIFY_NAV_IDS = Object.keys(caasifyRouteMap);
65
+
66
+ export { CAASIFY_NAV_IDS, CAASIFY_WALLET_CURRENCY, caasifyHeaderCTA, caasifyLogo, caasifyNavigation, caasifyPathToId, caasifyRouteMap, resolveCurrentId };
67
+ //# sourceMappingURL=chunk-PZYJ3H4D.js.map
68
+ //# sourceMappingURL=chunk-PZYJ3H4D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/navigation.ts"],"names":[],"mappings":"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","file":"chunk-PZYJ3H4D.js","sourcesContent":["/* ═══════════════════════════════════════════════════════════════\n @sdvf23rvfa43f/sidebar-header — Navigation Configuration\n ═══════════════════════════════════════════════════════════════\n Pure data module — no React dependency.\n Import standalone: import { ... } from '@sdvf23rvfa43f/sidebar-header/navigation'\n ═══════════════════════════════════════════════════════════════ */\n\nimport {\n LayoutDashboard, Server, Shield, Zap, Globe, Network,\n AppWindow, Layers, HardDrive,\n Receipt, LifeBuoy, TicketPlus, Users, ShoppingCart,\n} from 'lucide-react';\nimport type { SidebarNavSection, SidebarCTAButton, SidebarLogo, SidebarWallet } from '@sdvf23rvfa43f/stealth-glass';\n\n// ─── Contextual Navigation ──────────────────────────────────\n\n/**\n * Returned by a `contextualNav` resolver to inject a dynamic sidebar section.\n * The section is spliced between Overview and Account when the user drills\n * into a specific service (e.g. individual server list under Servers).\n */\nexport interface ContextualNav {\n /** Navigation section to inject (rendered between Overview and Account) */\n section: SidebarNavSection;\n /** Route map entries for contextual items (merged with canonical map) */\n routeMap: Record<string, string>;\n}\n\n// ─── Logo ────────────────────────────────────────────────────\n\nexport const caasifyLogo: SidebarLogo = {\n src: 'https://upload.caasify.com/logo/logo-70x70.png',\n alt: 'Caasify',\n title: 'Caasify',\n};\n\n// ─── Sidebar Navigation Sections ─────────────────────────────\n\nexport const caasifyNavigation: SidebarNavSection[] = [\n {\n category: 'Overview',\n items: [\n { id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard },\n { id: 'cloud-vps', label: 'Servers', icon: Server },\n { id: 'vpn', label: 'VPNs', icon: Shield },\n { id: 'app', label: 'Application', icon: AppWindow, badge: 'SOON' },\n { id: 'platform', label: 'Platform', icon: Layers, badge: 'SOON' },\n { id: 's3', label: 'S3', icon: HardDrive, badge: 'SOON' },\n { id: 'serverless', label: 'Functions', icon: Zap, badge: 'BETA' },\n { id: 'domain', label: 'Domain', icon: Globe, badge: 'BETA' },\n { id: 'route53', label: 'DNS Service', icon: Network, badge: 'BETA' },\n ],\n },\n {\n category: 'Account',\n items: [\n { id: 'billing', label: 'View Invoices', icon: Receipt },\n { id: 'support', label: 'Support', icon: LifeBuoy },\n { id: 'support-open-ticket', label: 'Open Ticket', icon: TicketPlus },\n { id: 'become-reseller', label: 'Become Reseller', icon: Users },\n ],\n },\n];\n\n// ─── Route Map ───────────────────────────────────────────────\n\n/** Maps each nav item `id` to its URL path. */\nexport const caasifyRouteMap: Record<string, string> = {\n 'dashboard': '/',\n 'cloud-vps': '/cloud-vps',\n 'vpn': '/vpn',\n 'app': '/app',\n 'platform': '/platform',\n 's3': '/s3',\n 'serverless': '/serverless',\n 'domain': '/domain',\n 'route53': '/route53',\n 'billing': '/billing',\n 'support': '/support',\n 'support-open-ticket': '/support/open-ticket',\n 'become-reseller': '/become-reseller',\n 'order-service': '/order-service',\n};\n\n/** Reverse lookup: URL path -> nav item `id`. */\nexport const caasifyPathToId: Record<string, string> = Object.fromEntries(\n Object.entries(caasifyRouteMap).map(([id, path]) => [path, id]),\n);\n\n// ─── Header CTA ──────────────────────────────────────────────\n\n/** Create Order button configuration for the sidebar. */\nexport const caasifyHeaderCTA = {\n label: 'Create Order',\n icon: ShoppingCart,\n route: '/order-service',\n} as const;\n\n// ─── Wallet defaults ─────────────────────────────────────────\n\n/** Default wallet currency symbol. */\nexport const CAASIFY_WALLET_CURRENCY = '€';\n\n// ─── Helper: resolve currentId from pathname ─────────────────\n\n/**\n * Resolves the active sidebar nav `id` from a URL pathname.\n * Uses exact match first, then longest-prefix match, fallback to 'dashboard'.\n */\nexport function resolveCurrentId(pathname: string): string {\n // Exact match\n if (caasifyPathToId[pathname]) return caasifyPathToId[pathname];\n\n // Longest prefix match (skip '/' to avoid false positives)\n const match = Object.entries(caasifyRouteMap)\n .filter(([, path]) => path !== '/' && pathname.startsWith(path))\n .sort((a, b) => b[1].length - a[1].length)[0];\n\n return match?.[0] ?? 'dashboard';\n}\n\n// ─── All nav item IDs (useful for type narrowing) ────────────\n\nexport const CAASIFY_NAV_IDS = Object.keys(caasifyRouteMap) as ReadonlyArray<string>;"]}
@@ -0,0 +1,8 @@
1
+ export { C as CaasifyRouterOptions, a as CaasifyShell, b as CaasifyShellProps, R as ROUTE_IDS, c as buildCaasifyRoutes, d as buildChildRoutes, e as createCaasifyRouter, f as defaultPageMap } from './routes-D0GrmQ4o.js';
2
+ export { CAASIFY_NAV_IDS, CAASIFY_WALLET_CURRENCY, ContextualNav, caasifyHeaderCTA, caasifyLogo, caasifyNavigation, caasifyPathToId, caasifyRouteMap, resolveCurrentId } from './navigation.js';
3
+ export { P as PlaceholderPage, a as PlaceholderPageProps } from './PlaceholderPage-ftRS9Unp.js';
4
+ import 'react-router';
5
+ import 'react';
6
+ import 'react/jsx-runtime';
7
+ import '@sdvf23rvfa43f/stealth-glass';
8
+ import 'lucide-react';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { CaasifyShell, ROUTE_IDS, buildCaasifyRoutes, buildChildRoutes, createCaasifyRouter, defaultPageMap } from './chunk-PJ3VQ2RZ.js';
2
+ export { CAASIFY_NAV_IDS, CAASIFY_WALLET_CURRENCY, caasifyHeaderCTA, caasifyLogo, caasifyNavigation, caasifyPathToId, caasifyRouteMap, resolveCurrentId } from './chunk-PZYJ3H4D.js';
3
+ export { PlaceholderPage } from './chunk-JNP6BURZ.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,37 @@
1
+ import * as react from 'react';
2
+ import * as lucide_react from 'lucide-react';
3
+ import { SidebarNavSection, SidebarLogo } from '@sdvf23rvfa43f/stealth-glass';
4
+
5
+ /**
6
+ * Returned by a `contextualNav` resolver to inject a dynamic sidebar section.
7
+ * The section is spliced between Overview and Account when the user drills
8
+ * into a specific service (e.g. individual server list under Servers).
9
+ */
10
+ interface ContextualNav {
11
+ /** Navigation section to inject (rendered between Overview and Account) */
12
+ section: SidebarNavSection;
13
+ /** Route map entries for contextual items (merged with canonical map) */
14
+ routeMap: Record<string, string>;
15
+ }
16
+ declare const caasifyLogo: SidebarLogo;
17
+ declare const caasifyNavigation: SidebarNavSection[];
18
+ /** Maps each nav item `id` to its URL path. */
19
+ declare const caasifyRouteMap: Record<string, string>;
20
+ /** Reverse lookup: URL path -> nav item `id`. */
21
+ declare const caasifyPathToId: Record<string, string>;
22
+ /** Create Order button configuration for the sidebar. */
23
+ declare const caasifyHeaderCTA: {
24
+ readonly label: "Create Order";
25
+ readonly icon: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
26
+ readonly route: "/order-service";
27
+ };
28
+ /** Default wallet currency symbol. */
29
+ declare const CAASIFY_WALLET_CURRENCY = "\u20AC";
30
+ /**
31
+ * Resolves the active sidebar nav `id` from a URL pathname.
32
+ * Uses exact match first, then longest-prefix match, fallback to 'dashboard'.
33
+ */
34
+ declare function resolveCurrentId(pathname: string): string;
35
+ declare const CAASIFY_NAV_IDS: ReadonlyArray<string>;
36
+
37
+ export { CAASIFY_NAV_IDS, CAASIFY_WALLET_CURRENCY, type ContextualNav, caasifyHeaderCTA, caasifyLogo, caasifyNavigation, caasifyPathToId, caasifyRouteMap, resolveCurrentId };
@@ -0,0 +1,3 @@
1
+ export { CAASIFY_NAV_IDS, CAASIFY_WALLET_CURRENCY, caasifyHeaderCTA, caasifyLogo, caasifyNavigation, caasifyPathToId, caasifyRouteMap, resolveCurrentId } from './chunk-PZYJ3H4D.js';
2
+ //# sourceMappingURL=navigation.js.map
3
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"navigation.js"}
@@ -0,0 +1,35 @@
1
+ export { P as PlaceholderPage, a as PlaceholderPageProps } from '../PlaceholderPage-ftRS9Unp.js';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import 'react';
4
+
5
+ declare function DashboardPage(): react_jsx_runtime.JSX.Element;
6
+
7
+ declare function ServersPage(): react_jsx_runtime.JSX.Element;
8
+
9
+ declare function VpnPage(): react_jsx_runtime.JSX.Element;
10
+
11
+ declare function ApplicationPage(): react_jsx_runtime.JSX.Element;
12
+
13
+ declare function PlatformPage(): react_jsx_runtime.JSX.Element;
14
+
15
+ declare function S3Page(): react_jsx_runtime.JSX.Element;
16
+
17
+ declare function FunctionsPage(): react_jsx_runtime.JSX.Element;
18
+
19
+ declare function DomainPage(): react_jsx_runtime.JSX.Element;
20
+
21
+ declare function DnsServicePage(): react_jsx_runtime.JSX.Element;
22
+
23
+ declare function BillingPage(): react_jsx_runtime.JSX.Element;
24
+
25
+ declare function SupportPage(): react_jsx_runtime.JSX.Element;
26
+
27
+ declare function OpenTicketPage(): react_jsx_runtime.JSX.Element;
28
+
29
+ declare function BecomeResellerPage(): react_jsx_runtime.JSX.Element;
30
+
31
+ declare function OrderServicePage(): react_jsx_runtime.JSX.Element;
32
+
33
+ declare function NotFoundPage(): react_jsx_runtime.JSX.Element;
34
+
35
+ export { ApplicationPage, BecomeResellerPage, BillingPage, DashboardPage, DnsServicePage, DomainPage, FunctionsPage, NotFoundPage, OpenTicketPage, OrderServicePage, PlatformPage, S3Page, ServersPage, SupportPage, VpnPage };
@@ -0,0 +1,3 @@
1
+ export { ApplicationPage, BecomeResellerPage, BillingPage, DashboardPage, DnsServicePage, DomainPage, FunctionsPage, NotFoundPage, OpenTicketPage, OrderServicePage, PlaceholderPage, PlatformPage, S3Page, ServersPage, SupportPage, VpnPage } from '../chunk-JNP6BURZ.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,96 @@
1
+ import * as react_router from 'react-router';
2
+ import { RouteObject } from 'react-router';
3
+ import { ReactNode, ComponentType } from 'react';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { SidebarUser, AppShellProps } from '@sdvf23rvfa43f/stealth-glass';
6
+ import { ContextualNav } from './navigation.js';
7
+
8
+ interface CaasifyShellProps {
9
+ children: ReactNode;
10
+ /** Auth state */
11
+ isAuthenticated: boolean;
12
+ user?: SidebarUser;
13
+ onSignOut?: () => void;
14
+ /** Wallet balance (shown in sidebar). Omit to hide wallet widget. */
15
+ walletBalance?: number;
16
+ /** Wallet currency symbol. Default: '€' */
17
+ walletCurrency?: string;
18
+ /** Callback when "Add Funds" is clicked. Defaults to navigate('/billing'). */
19
+ onAddFunds?: () => void;
20
+ /** Override navigation sections (advanced). Default: Caasify canonical nav. */
21
+ navigation?: AppShellProps['navigation'];
22
+ /** Override route map (advanced). Default: caasifyRouteMap. */
23
+ routeMap?: Record<string, string>;
24
+ /** Extra AppShell props forwarded directly (headerLeftSlot, ambientColors, etc.) */
25
+ headerLeftSlot?: AppShellProps['headerLeftSlot'];
26
+ headerRightSlot?: AppShellProps['headerRightSlot'];
27
+ ambientColors?: AppShellProps['ambientColors'];
28
+ contentMaxWidth?: AppShellProps['contentMaxWidth'];
29
+ isLoading?: AppShellProps['isLoading'];
30
+ footerSlot?: AppShellProps['footerSlot'];
31
+ /**
32
+ * Contextual sidebar section resolver (Option B).
33
+ * Called with the resolved canonical `currentId` on every render.
34
+ * Return a `ContextualNav` to inject a dynamic section between Overview and Account,
35
+ * or `null` to show the default 2-section layout.
36
+ *
37
+ * The resolver should be pure and cheap. Memoize with `useCallback` if needed.
38
+ */
39
+ contextualNav?: (currentId: string) => ContextualNav | null;
40
+ }
41
+ declare function CaasifyShell({ children, isAuthenticated, user, onSignOut, walletBalance, walletCurrency, onAddFunds, navigation, routeMap, headerLeftSlot, headerRightSlot, ambientColors, contentMaxWidth, isLoading, footerSlot, contextualNav, }: CaasifyShellProps): react_jsx_runtime.JSX.Element;
42
+
43
+ declare const ROUTE_IDS: {
44
+ readonly ROOT: "root";
45
+ readonly DASHBOARD: "dashboard";
46
+ readonly SERVERS: "cloud-vps";
47
+ readonly VPN: "vpn";
48
+ readonly APPLICATION: "app";
49
+ readonly PLATFORM: "platform";
50
+ readonly S3: "s3";
51
+ readonly FUNCTIONS: "serverless";
52
+ readonly DOMAIN: "domain";
53
+ readonly DNS_SERVICE: "route53";
54
+ readonly BILLING: "billing";
55
+ readonly SUPPORT: "support";
56
+ readonly OPEN_TICKET: "support-open-ticket";
57
+ readonly BECOME_RESELLER: "become-reseller";
58
+ readonly ORDER_SERVICE: "order-service";
59
+ readonly NOT_FOUND: "not-found";
60
+ };
61
+ /** Default page component for each route. Override via `pageOverrides`. */
62
+ declare const defaultPageMap: Record<string, ComponentType>;
63
+ /**
64
+ * Canonical child routes for the Caasify shell.
65
+ * Each route uses a default placeholder page that can be overridden.
66
+ */
67
+ declare function buildChildRoutes(pageOverrides?: Partial<Record<string, ComponentType>>, extraRoutes?: RouteObject[]): RouteObject[];
68
+ interface CaasifyRouterOptions {
69
+ /** Props forwarded to CaasifyShell (auth, user, wallet, etc.) */
70
+ shellProps?: Partial<CaasifyShellProps>;
71
+ /** Override specific page components by route ID. */
72
+ pageOverrides?: Partial<Record<string, ComponentType>>;
73
+ /** Extra child routes appended inside the shell layout. */
74
+ extraRoutes?: RouteObject[];
75
+ /** Extra top-level routes added OUTSIDE the shell (e.g. /login). */
76
+ topLevelRoutes?: RouteObject[];
77
+ /** Custom root component. If provided, shellProps is ignored. */
78
+ RootComponent?: ComponentType;
79
+ }
80
+ /**
81
+ * Build the full Caasify route array (not yet a router).
82
+ * Use this if you want to combine with your own `createBrowserRouter` call.
83
+ */
84
+ declare function buildCaasifyRoutes(options?: CaasifyRouterOptions): RouteObject[];
85
+ /**
86
+ * One-liner: creates a complete `BrowserRouter` with the Caasify shell + all routes.
87
+ *
88
+ * ```tsx
89
+ * import { createCaasifyRouter } from '@sdvf23rvfa43f/sidebar-header/routes';
90
+ * const router = createCaasifyRouter({ shellProps: { isAuthenticated: true } });
91
+ * <RouterProvider router={router} />
92
+ * ```
93
+ */
94
+ declare function createCaasifyRouter(options?: CaasifyRouterOptions): react_router.DataRouter;
95
+
96
+ export { type CaasifyRouterOptions as C, ROUTE_IDS as R, CaasifyShell as a, type CaasifyShellProps as b, buildCaasifyRoutes as c, buildChildRoutes as d, createCaasifyRouter as e, defaultPageMap as f };
@@ -0,0 +1,7 @@
1
+ import 'react-router';
2
+ import 'react';
3
+ export { C as CaasifyRouterOptions, R as ROUTE_IDS, c as buildCaasifyRoutes, d as buildChildRoutes, e as createCaasifyRouter, f as defaultPageMap } from './routes-D0GrmQ4o.js';
4
+ import 'react/jsx-runtime';
5
+ import '@sdvf23rvfa43f/stealth-glass';
6
+ import './navigation.js';
7
+ import 'lucide-react';
package/dist/routes.js ADDED
@@ -0,0 +1,5 @@
1
+ export { ROUTE_IDS, buildCaasifyRoutes, buildChildRoutes, createCaasifyRouter, defaultPageMap } from './chunk-PJ3VQ2RZ.js';
2
+ import './chunk-PZYJ3H4D.js';
3
+ import './chunk-JNP6BURZ.js';
4
+ //# sourceMappingURL=routes.js.map
5
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"routes.js"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@sdvf23rvfa43f/sidebar-header",
3
+ "version": "1.2.0",
4
+ "description": "Caasify shared sidebar + header navigation shell — pre-wired AppShell with canonical nav structure",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./navigation": {
15
+ "import": "./dist/navigation.js",
16
+ "types": "./dist/navigation.d.ts"
17
+ },
18
+ "./routes": {
19
+ "import": "./dist/routes.js",
20
+ "types": "./dist/routes.d.ts"
21
+ },
22
+ "./pages": {
23
+ "import": "./dist/pages/index.js",
24
+ "types": "./dist/pages/index.d.ts"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist/**/*"
29
+ ],
30
+ "scripts": {
31
+ "build": "npx tsup",
32
+ "dev": "npx tsup --watch",
33
+ "clean": "rm -rf dist",
34
+ "typecheck": "npx tsc --noEmit",
35
+ "verify": "node -e \"const p=require('./package.json'); if(p.name!=='@sdvf23rvfa43f/sidebar-header'){console.error('WRONG PACKAGE: '+p.name);process.exit(1)} console.log('OK: '+p.name+'@'+p.version)\"",
36
+ "prepublishOnly": "npm run verify && npm run clean && npm run build"
37
+ },
38
+ "keywords": [
39
+ "caasify",
40
+ "sidebar",
41
+ "header",
42
+ "navigation",
43
+ "appshell",
44
+ "stealth-glass",
45
+ "react"
46
+ ],
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/caasify/stealth-glass-theme.git",
50
+ "directory": "sidebar-header"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public",
54
+ "registry": "https://registry.npmjs.org/"
55
+ },
56
+ "license": "MIT",
57
+ "peerDependencies": {
58
+ "react": "^18.0.0 || ^19.0.0",
59
+ "react-dom": "^18.0.0 || ^19.0.0",
60
+ "react-router": ">=7.0.0",
61
+ "lucide-react": ">=0.300.0",
62
+ "@sdvf23rvfa43f/stealth-glass": ">=1.3.0"
63
+ },
64
+ "devDependencies": {
65
+ "tsup": "^8.0.0",
66
+ "typescript": "^5.0.0",
67
+ "react": "^18.0.0",
68
+ "react-dom": "^18.0.0",
69
+ "@types/react": "^18.0.0",
70
+ "@types/react-dom": "^18.0.0",
71
+ "react-router": "^7.0.0",
72
+ "lucide-react": ">=0.300.0"
73
+ }
74
+ }