@jxrstudios/jxr 1.0.10 → 1.1.11

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.
Files changed (87) hide show
  1. package/bin/jxr.js +6 -0
  2. package/dist/index.js +57 -2
  3. package/dist/jxr-server-manager.d.ts.map +1 -1
  4. package/package.json +1 -1
  5. package/src/jxr-server-manager.ts +65 -2
  6. package/zzz_react_template/App.tsx +43 -156
  7. package/zzz_react_template/components/ErrorBoundary.tsx +62 -0
  8. package/zzz_react_template/components/ManusDialog.tsx +85 -0
  9. package/zzz_react_template/components/Map.tsx +155 -0
  10. package/zzz_react_template/components/jxr/CodeEditor.tsx +313 -0
  11. package/zzz_react_template/components/jxr/FileExplorer.tsx +230 -0
  12. package/zzz_react_template/components/jxr/IDEShell.tsx +159 -0
  13. package/zzz_react_template/components/jxr/LandingPage.tsx +414 -0
  14. package/zzz_react_template/components/jxr/LivePreview.tsx +169 -0
  15. package/zzz_react_template/components/jxr/PerformanceDashboard.tsx +379 -0
  16. package/zzz_react_template/components/jxr/TopBar.tsx +149 -0
  17. package/zzz_react_template/components/ui/accordion.tsx +64 -0
  18. package/zzz_react_template/components/ui/alert-dialog.tsx +155 -0
  19. package/zzz_react_template/components/ui/alert.tsx +66 -0
  20. package/zzz_react_template/components/ui/aspect-ratio.tsx +9 -0
  21. package/zzz_react_template/components/ui/avatar.tsx +51 -0
  22. package/zzz_react_template/components/ui/badge.tsx +46 -0
  23. package/zzz_react_template/components/ui/breadcrumb.tsx +109 -0
  24. package/zzz_react_template/components/ui/button-group.tsx +83 -0
  25. package/zzz_react_template/components/ui/button.tsx +60 -0
  26. package/zzz_react_template/components/ui/calendar.tsx +211 -0
  27. package/zzz_react_template/components/ui/card.tsx +92 -0
  28. package/zzz_react_template/components/ui/carousel.tsx +239 -0
  29. package/zzz_react_template/components/ui/chart.tsx +355 -0
  30. package/zzz_react_template/components/ui/checkbox.tsx +30 -0
  31. package/zzz_react_template/components/ui/collapsible.tsx +31 -0
  32. package/zzz_react_template/components/ui/command.tsx +184 -0
  33. package/zzz_react_template/components/ui/context-menu.tsx +250 -0
  34. package/zzz_react_template/components/ui/dialog.tsx +209 -0
  35. package/zzz_react_template/components/ui/drawer.tsx +133 -0
  36. package/zzz_react_template/components/ui/dropdown-menu.tsx +255 -0
  37. package/zzz_react_template/components/ui/empty.tsx +104 -0
  38. package/zzz_react_template/components/ui/field.tsx +242 -0
  39. package/zzz_react_template/components/ui/form.tsx +168 -0
  40. package/zzz_react_template/components/ui/hover-card.tsx +42 -0
  41. package/zzz_react_template/components/ui/input-group.tsx +168 -0
  42. package/zzz_react_template/components/ui/input-otp.tsx +75 -0
  43. package/zzz_react_template/components/ui/input.tsx +70 -0
  44. package/zzz_react_template/components/ui/item.tsx +193 -0
  45. package/zzz_react_template/components/ui/kbd.tsx +28 -0
  46. package/zzz_react_template/components/ui/label.tsx +22 -0
  47. package/zzz_react_template/components/ui/menubar.tsx +274 -0
  48. package/zzz_react_template/components/ui/navigation-menu.tsx +168 -0
  49. package/zzz_react_template/components/ui/pagination.tsx +127 -0
  50. package/zzz_react_template/components/ui/popover.tsx +46 -0
  51. package/zzz_react_template/components/ui/progress.tsx +29 -0
  52. package/zzz_react_template/components/ui/radio-group.tsx +43 -0
  53. package/zzz_react_template/components/ui/resizable.tsx +54 -0
  54. package/zzz_react_template/components/ui/scroll-area.tsx +56 -0
  55. package/zzz_react_template/components/ui/select.tsx +185 -0
  56. package/zzz_react_template/components/ui/separator.tsx +26 -0
  57. package/zzz_react_template/components/ui/sheet.tsx +139 -0
  58. package/zzz_react_template/components/ui/sidebar.tsx +734 -0
  59. package/zzz_react_template/components/ui/skeleton.tsx +13 -0
  60. package/zzz_react_template/components/ui/slider.tsx +61 -0
  61. package/zzz_react_template/components/ui/sonner.tsx +23 -0
  62. package/zzz_react_template/components/ui/spinner.tsx +16 -0
  63. package/zzz_react_template/components/ui/switch.tsx +29 -0
  64. package/zzz_react_template/components/ui/table.tsx +114 -0
  65. package/zzz_react_template/components/ui/tabs.tsx +64 -0
  66. package/zzz_react_template/components/ui/textarea.tsx +67 -0
  67. package/zzz_react_template/components/ui/toggle-group.tsx +73 -0
  68. package/zzz_react_template/components/ui/toggle.tsx +45 -0
  69. package/zzz_react_template/components/ui/tooltip.tsx +59 -0
  70. package/zzz_react_template/const.ts +17 -0
  71. package/zzz_react_template/contexts/JXRContext.tsx +264 -0
  72. package/zzz_react_template/contexts/ThemeContext.tsx +64 -0
  73. package/zzz_react_template/hooks/useComposition.ts +81 -0
  74. package/zzz_react_template/hooks/useMobile.tsx +21 -0
  75. package/zzz_react_template/hooks/usePersistFn.ts +20 -0
  76. package/zzz_react_template/index.css +518 -11
  77. package/zzz_react_template/lib/jxr-runtime/index.ts +201 -0
  78. package/zzz_react_template/lib/jxr-runtime/module-resolver.ts +520 -0
  79. package/zzz_react_template/lib/jxr-runtime/moq-transport.ts +267 -0
  80. package/zzz_react_template/lib/jxr-runtime/web-crypto.ts +279 -0
  81. package/zzz_react_template/lib/jxr-runtime/worker-pool.ts +321 -0
  82. package/zzz_react_template/lib/utils.ts +6 -0
  83. package/zzz_react_template/main.tsx +4 -9
  84. package/zzz_react_template/pages/Docs.tsx +955 -0
  85. package/zzz_react_template/pages/Home.tsx +1080 -0
  86. package/zzz_react_template/pages/NotFound.tsx +105 -0
  87. package/zzz_react_template/tsconfig.json +24 -0
package/bin/jxr.js CHANGED
@@ -55,6 +55,12 @@ if (command === "init") {
55
55
  );
56
56
  }
57
57
 
58
+ // Copy tsconfig.json
59
+ await cp(
60
+ path.join(templateDir, "tsconfig.json"),
61
+ path.join(projectDir, "tsconfig.json")
62
+ );
63
+
58
64
  console.log(`✅ Project created: ${projectDir}`);
59
65
  console.log("");
60
66
  console.log("Next steps:");
package/dist/index.js CHANGED
@@ -1815,7 +1815,55 @@ var JXRServerManager = class {
1815
1815
  return;
1816
1816
  }
1817
1817
  if (vfsPath.endsWith(".css")) {
1818
- const escapedCSS = file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
1818
+ let cssContent = file.content;
1819
+ if (vfsPath === "/src/index.css") {
1820
+ try {
1821
+ const fs = await import("fs");
1822
+ const compiledPath = path.join(process.cwd(), "src", "index.compiled.css");
1823
+ if (fs.existsSync(compiledPath)) {
1824
+ cssContent = fs.readFileSync(compiledPath, "utf-8");
1825
+ console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
1826
+ } else {
1827
+ const { execSync } = await import("child_process");
1828
+ const os = await import("os");
1829
+ const tmpDir = os.tmpdir();
1830
+ const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
1831
+ const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
1832
+ fs.writeFileSync(inputFile, cssContent);
1833
+ try {
1834
+ execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
1835
+ timeout: 3e4,
1836
+ stdio: "pipe"
1837
+ });
1838
+ cssContent = fs.readFileSync(outputFile, "utf-8");
1839
+ fs.unlinkSync(inputFile);
1840
+ fs.unlinkSync(outputFile);
1841
+ console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
1842
+ } catch {
1843
+ const js2 = `
1844
+ const tailwindScript = document.createElement('script');
1845
+ tailwindScript.src = 'https://cdn.tailwindcss.com';
1846
+ tailwindScript.onload = function() {
1847
+ const style = document.createElement('style');
1848
+ style.textContent = \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
1849
+ document.head.appendChild(style);
1850
+ };
1851
+ document.head.appendChild(tailwindScript);
1852
+ export default \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
1853
+ `;
1854
+ res.writeHead(200, {
1855
+ "Content-Type": "application/javascript",
1856
+ "Cache-Control": "no-cache"
1857
+ });
1858
+ res.end(js2);
1859
+ return;
1860
+ }
1861
+ }
1862
+ } catch (error) {
1863
+ console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
1864
+ }
1865
+ }
1866
+ const escapedCSS = cssContent.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
1819
1867
  const js = `
1820
1868
  const style = document.createElement('style');
1821
1869
  style.textContent = \`${escapedCSS}\`;
@@ -1949,7 +1997,14 @@ export default \`${escapedCSS}\`;
1949
1997
  <head>
1950
1998
  <meta charset="UTF-8">
1951
1999
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1952
- <title>JXR App</title>
2000
+ <title>JXR.js \u2014 Edge OS Runtime Framework</title>
2001
+ <meta name="description" content="JXR.js is the next-generation edge runtime framework for React Native and React. MoQ transport, Web Crypto, Worker pools.">
2002
+
2003
+ <!-- Google Fonts -->
2004
+ <link rel="preconnect" href="https://fonts.googleapis.com">
2005
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
2006
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
2007
+
1953
2008
  <script type="importmap">
1954
2009
  ${JSON.stringify(importMap)}
1955
2010
  <\/script>
@@ -1 +1 @@
1
- {"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2HtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B,OAAO,CAAC,YAAY;CA+GrB"}
1
+ {"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmLtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B,OAAO,CAAC,YAAY;CAsHrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxrstudios/jxr",
3
- "version": "1.0.10",
3
+ "version": "1.1.11",
4
4
  "description": "JXR.js — Edge OS Runtime Framework for elite developers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -249,7 +249,63 @@ export class JXRServerManager {
249
249
 
250
250
  // Serve CSS files as JavaScript that injects the CSS
251
251
  if (vfsPath.endsWith('.css')) {
252
- const escapedCSS = file.content
252
+ let cssContent = file.content;
253
+
254
+ // Check for pre-compiled Tailwind CSS first
255
+ if (vfsPath === '/src/index.css') {
256
+ try {
257
+ const fs = await import('fs');
258
+ const compiledPath = path.join(process.cwd(), 'src', 'index.compiled.css');
259
+ if (fs.existsSync(compiledPath)) {
260
+ cssContent = fs.readFileSync(compiledPath, 'utf-8');
261
+ console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
262
+ } else {
263
+ // Try to compile on-the-fly
264
+ const { execSync } = await import('child_process');
265
+ const os = await import('os');
266
+
267
+ const tmpDir = os.tmpdir();
268
+ const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
269
+ const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
270
+
271
+ fs.writeFileSync(inputFile, cssContent);
272
+
273
+ try {
274
+ execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
275
+ timeout: 30000,
276
+ stdio: 'pipe'
277
+ });
278
+ cssContent = fs.readFileSync(outputFile, 'utf-8');
279
+ fs.unlinkSync(inputFile);
280
+ fs.unlinkSync(outputFile);
281
+ console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
282
+ } catch {
283
+ // CDN fallback
284
+ const js = `
285
+ const tailwindScript = document.createElement('script');
286
+ tailwindScript.src = 'https://cdn.tailwindcss.com';
287
+ tailwindScript.onload = function() {
288
+ const style = document.createElement('style');
289
+ style.textContent = \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
290
+ document.head.appendChild(style);
291
+ };
292
+ document.head.appendChild(tailwindScript);
293
+ export default \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
294
+ `;
295
+ res.writeHead(200, {
296
+ "Content-Type": "application/javascript",
297
+ "Cache-Control": "no-cache"
298
+ });
299
+ res.end(js);
300
+ return;
301
+ }
302
+ }
303
+ } catch (error: any) {
304
+ console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
305
+ }
306
+ }
307
+
308
+ const escapedCSS = cssContent
253
309
  .replace(/\\/g, '\\\\')
254
310
  .replace(/`/g, '\\`')
255
311
  .replace(/\$/g, '\\$');
@@ -411,7 +467,14 @@ export default \`${escapedCSS}\`;
411
467
  <head>
412
468
  <meta charset="UTF-8">
413
469
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
414
- <title>JXR App</title>
470
+ <title>JXR.js — Edge OS Runtime Framework</title>
471
+ <meta name="description" content="JXR.js is the next-generation edge runtime framework for React Native and React. MoQ transport, Web Crypto, Worker pools.">
472
+
473
+ <!-- Google Fonts -->
474
+ <link rel="preconnect" href="https://fonts.googleapis.com">
475
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
476
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
477
+
415
478
  <script type="importmap">
416
479
  ${JSON.stringify(importMap)}
417
480
  </script>
@@ -1,160 +1,47 @@
1
- import React, { useState } from 'react'
2
-
3
- const FEATURES = [
4
- { icon: '⚡', title: 'React 19', desc: 'Latest React with automatic batching and concurrent features' },
5
- { icon: '🎨', title: 'Tailwind CSS', desc: 'Utility-first styling with the Tailwind CDN in preview' },
6
- { icon: '📦', title: 'TypeScript', desc: 'Full type safety across your entire codebase' },
7
- { icon: '🚀', title: 'Vite', desc: 'Lightning-fast HMR and optimized production builds' },
8
- ]
1
+ /**
2
+ * JXR.js Marketing Website — App.tsx
3
+ * LavaFlow OS Design System
4
+ * Powered by JXR Studios × DamascusAI
5
+ */
6
+
7
+ import { Toaster } from "@/components/ui/sonner";
8
+ import { TooltipProvider } from "@/components/ui/tooltip";
9
+ import { Route, Switch } from "wouter";
10
+ import ErrorBoundary from "./components/ErrorBoundary";
11
+ import { ThemeProvider } from "./contexts/ThemeContext";
12
+ import Home from "./pages/Home";
13
+ import DocsPage from "./pages/Docs";
14
+ import NotFound from "./pages/NotFound";
15
+
16
+ function Router() {
17
+ return (
18
+ <Switch>
19
+ <Route path="/" component={Home} />
20
+ <Route path="/docs" component={DocsPage} />
21
+ <Route path="/docs/:section" component={DocsPage} />
22
+ <Route component={NotFound} />
23
+ </Switch>
24
+ );
25
+ }
9
26
 
10
27
  export default function App() {
11
- const [count, setCount] = useState(0)
12
-
13
28
  return (
14
- <div style={{
15
- minHeight: '100vh',
16
- background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)',
17
- display: 'flex',
18
- flexDirection: 'column',
19
- alignItems: 'center',
20
- justifyContent: 'center',
21
- padding: '2rem',
22
- fontFamily: "'Inter', system-ui, -apple-system, sans-serif",
23
- color: '#e2e8f0',
24
- }}>
25
- {/* Hero Card */}
26
- <div style={{
27
- background: 'rgba(255,255,255,0.05)',
28
- backdropFilter: 'blur(20px)',
29
- borderRadius: '1.5rem',
30
- border: '1px solid rgba(255,255,255,0.1)',
31
- padding: '3rem',
32
- maxWidth: '640px',
33
- width: '100%',
34
- textAlign: 'center',
35
- boxShadow: '0 25px 50px -12px rgba(0,0,0,0.5)',
36
- }}>
37
- {/* Logo */}
38
- <div style={{
39
- width: '64px',
40
- height: '64px',
41
- borderRadius: '16px',
42
- background: 'linear-gradient(135deg, #6366f1, #a855f7, #ec4899)',
43
- display: 'flex',
44
- alignItems: 'center',
45
- justifyContent: 'center',
46
- margin: '0 auto 1.5rem',
47
- fontSize: '1.5rem',
48
- fontWeight: 'bold',
49
- color: 'white',
50
- boxShadow: '0 0 30px rgba(99,102,241,0.4)',
51
- }}>
52
- x0
53
- </div>
54
-
55
- <h1 style={{
56
- fontSize: '2.25rem',
57
- fontWeight: 800,
58
- marginBottom: '0.75rem',
59
- background: 'linear-gradient(135deg, #c7d2fe, #e9d5ff, #fbcfe8)',
60
- WebkitBackgroundClip: 'text',
61
- WebkitTextFillColor: 'transparent',
62
- lineHeight: 1.2,
63
- }}>
64
- Your App is Live
65
- </h1>
66
-
67
- <p style={{
68
- fontSize: '1.1rem',
69
- color: 'rgba(226,232,240,0.7)',
70
- marginBottom: '2rem',
71
- lineHeight: 1.6,
72
- }}>
73
- This project is ready for development. Use the AI chat to describe
74
- what you want to build, or start editing files directly.
75
- </p>
76
-
77
- {/* Interactive Counter */}
78
- <div style={{
79
- display: 'flex',
80
- alignItems: 'center',
81
- justifyContent: 'center',
82
- gap: '1rem',
83
- marginBottom: '2.5rem',
84
- }}>
85
- <button
86
- onClick={() => setCount(c => c - 1)}
87
- style={{
88
- width: '40px', height: '40px', borderRadius: '12px',
89
- background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.15)',
90
- color: '#e2e8f0', fontSize: '1.25rem', cursor: 'pointer',
91
- display: 'flex', alignItems: 'center', justifyContent: 'center',
92
- transition: 'all 0.15s',
93
- }}
94
- onMouseEnter={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.2)')}
95
- onMouseLeave={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.1)')}
96
- >
97
-
98
- </button>
99
- <div style={{
100
- padding: '0.5rem 1.5rem',
101
- borderRadius: '12px',
102
- background: 'rgba(99,102,241,0.2)',
103
- border: '1px solid rgba(99,102,241,0.3)',
104
- fontSize: '1.25rem',
105
- fontWeight: 700,
106
- fontVariantNumeric: 'tabular-nums',
107
- minWidth: '80px',
108
- }}>
109
- {count}
110
- </div>
111
- <button
112
- onClick={() => setCount(c => c + 1)}
113
- style={{
114
- width: '40px', height: '40px', borderRadius: '12px',
115
- background: 'linear-gradient(135deg, #6366f1, #a855f7)',
116
- border: 'none', color: 'white', fontSize: '1.25rem', cursor: 'pointer',
117
- display: 'flex', alignItems: 'center', justifyContent: 'center',
118
- boxShadow: '0 0 20px rgba(99,102,241,0.3)',
119
- transition: 'all 0.15s',
29
+ <ErrorBoundary>
30
+ <ThemeProvider defaultTheme="dark">
31
+ <TooltipProvider>
32
+ <Toaster
33
+ theme="dark"
34
+ toastOptions={{
35
+ style: {
36
+ background: 'oklch(0.13 0.007 285)',
37
+ border: '1px solid oklch(1 0 0 / 10%)',
38
+ color: 'oklch(0.93 0.005 65)',
39
+ },
120
40
  }}
121
- onMouseEnter={e => (e.currentTarget.style.transform = 'scale(1.1)')}
122
- onMouseLeave={e => (e.currentTarget.style.transform = 'scale(1)')}
123
- >
124
- +
125
- </button>
126
- </div>
127
-
128
- {/* Feature Grid */}
129
- <div style={{
130
- display: 'grid',
131
- gridTemplateColumns: 'repeat(2, 1fr)',
132
- gap: '0.75rem',
133
- textAlign: 'left',
134
- }}>
135
- {FEATURES.map((f) => (
136
- <div key={f.title} style={{
137
- padding: '1rem',
138
- borderRadius: '12px',
139
- background: 'rgba(255,255,255,0.04)',
140
- border: '1px solid rgba(255,255,255,0.06)',
141
- }}>
142
- <div style={{ fontSize: '1.25rem', marginBottom: '0.25rem' }}>{f.icon}</div>
143
- <div style={{ fontWeight: 600, fontSize: '0.875rem', marginBottom: '0.25rem' }}>{f.title}</div>
144
- <div style={{ fontSize: '0.75rem', color: 'rgba(226,232,240,0.5)', lineHeight: 1.4 }}>{f.desc}</div>
145
- </div>
146
- ))}
147
- </div>
148
- </div>
149
-
150
- {/* Footer */}
151
- <p style={{
152
- marginTop: '2rem',
153
- fontSize: '0.8rem',
154
- color: 'rgba(226,232,240,0.3)',
155
- }}>
156
- Built with x0 · React 19 · TypeScript · Tailwind CSS
157
- </p>
158
- </div>
159
- )
160
- }
41
+ />
42
+ <Router />
43
+ </TooltipProvider>
44
+ </ThemeProvider>
45
+ </ErrorBoundary>
46
+ );
47
+ }
@@ -0,0 +1,62 @@
1
+ import { cn } from "@/lib/utils";
2
+ import { AlertTriangle, RotateCcw } from "lucide-react";
3
+ import { Component, ReactNode } from "react";
4
+
5
+ interface Props {
6
+ children: ReactNode;
7
+ }
8
+
9
+ interface State {
10
+ hasError: boolean;
11
+ error: Error | null;
12
+ }
13
+
14
+ class ErrorBoundary extends Component<Props, State> {
15
+ constructor(props: Props) {
16
+ super(props);
17
+ this.state = { hasError: false, error: null };
18
+ }
19
+
20
+ static getDerivedStateFromError(error: Error): State {
21
+ return { hasError: true, error };
22
+ }
23
+
24
+ render() {
25
+ if (this.state.hasError) {
26
+ return (
27
+ <div className="flex items-center justify-center min-h-screen p-8 bg-background">
28
+ <div className="flex flex-col items-center w-full max-w-2xl p-8">
29
+ <AlertTriangle
30
+ size={48}
31
+ className="text-destructive mb-6 flex-shrink-0"
32
+ />
33
+
34
+ <h2 className="text-xl mb-4">An unexpected error occurred.</h2>
35
+
36
+ <div className="p-4 w-full rounded bg-muted overflow-auto mb-6">
37
+ <pre className="text-sm text-muted-foreground whitespace-break-spaces">
38
+ {this.state.error?.stack}
39
+ </pre>
40
+ </div>
41
+
42
+ <button
43
+ onClick={() => window.location.reload()}
44
+ className={cn(
45
+ "flex items-center gap-2 px-4 py-2 rounded-lg",
46
+ "bg-primary text-primary-foreground",
47
+ "hover:opacity-90 cursor-pointer"
48
+ )}
49
+ >
50
+ <RotateCcw size={16} />
51
+ Reload Page
52
+ </button>
53
+ </div>
54
+ </div>
55
+ );
56
+ }
57
+
58
+ return this.props.children;
59
+ }
60
+ }
61
+
62
+ export default ErrorBoundary;
@@ -0,0 +1,85 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { Button } from "@/components/ui/button";
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogFooter,
9
+ DialogTitle,
10
+ } from "@/components/ui/dialog";
11
+
12
+ interface ManusDialogProps {
13
+ title?: string;
14
+ logo?: string;
15
+ open?: boolean;
16
+ onLogin: () => void;
17
+ onOpenChange?: (open: boolean) => void;
18
+ onClose?: () => void;
19
+ }
20
+
21
+ export function ManusDialog({
22
+ title,
23
+ logo,
24
+ open = false,
25
+ onLogin,
26
+ onOpenChange,
27
+ onClose,
28
+ }: ManusDialogProps) {
29
+ const [internalOpen, setInternalOpen] = useState(open);
30
+
31
+ useEffect(() => {
32
+ if (!onOpenChange) {
33
+ setInternalOpen(open);
34
+ }
35
+ }, [open, onOpenChange]);
36
+
37
+ const handleOpenChange = (nextOpen: boolean) => {
38
+ if (onOpenChange) {
39
+ onOpenChange(nextOpen);
40
+ } else {
41
+ setInternalOpen(nextOpen);
42
+ }
43
+
44
+ if (!nextOpen) {
45
+ onClose?.();
46
+ }
47
+ };
48
+
49
+ return (
50
+ <Dialog
51
+ open={onOpenChange ? open : internalOpen}
52
+ onOpenChange={handleOpenChange}
53
+ >
54
+ <DialogContent className="py-5 bg-[#f8f8f7] rounded-[20px] w-[400px] shadow-[0px_4px_11px_0px_rgba(0,0,0,0.08)] border border-[rgba(0,0,0,0.08)] backdrop-blur-2xl p-0 gap-0 text-center">
55
+ <div className="flex flex-col items-center gap-2 p-5 pt-12">
56
+ {logo ? (
57
+ <div className="w-16 h-16 bg-white rounded-xl border border-[rgba(0,0,0,0.08)] flex items-center justify-center">
58
+ <img src={logo} alt="Dialog graphic" className="w-10 h-10 rounded-md" />
59
+ </div>
60
+ ) : null}
61
+
62
+ {/* Title and subtitle */}
63
+ {title ? (
64
+ <DialogTitle className="text-xl font-semibold text-[#34322d] leading-[26px] tracking-[-0.44px]">
65
+ {title}
66
+ </DialogTitle>
67
+ ) : null}
68
+ <DialogDescription className="text-sm text-[#858481] leading-5 tracking-[-0.154px]">
69
+ Please login with Manus to continue
70
+ </DialogDescription>
71
+ </div>
72
+
73
+ <DialogFooter className="px-5 py-5">
74
+ {/* Login button */}
75
+ <Button
76
+ onClick={onLogin}
77
+ className="w-full h-10 bg-[#1a1a19] hover:bg-[#1a1a19]/90 text-white rounded-[10px] text-sm font-medium leading-5 tracking-[-0.154px]"
78
+ >
79
+ Login with Manus
80
+ </Button>
81
+ </DialogFooter>
82
+ </DialogContent>
83
+ </Dialog>
84
+ );
85
+ }