upfynai-code 3.0.3 → 3.0.4
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.
- package/client/dist/api-docs.html +838 -838
- package/client/dist/assets/{AppContent-Bvg0CPCO.js → AppContent-CwrTP6TW.js} +43 -43
- package/client/dist/assets/BrowserPanel-0TLEl-IC.js +2 -0
- package/client/dist/assets/{CanvasFullScreen-BdiJ35aq.js → CanvasFullScreen-D1GWQsGL.js} +1 -1
- package/client/dist/assets/{CanvasWorkspace-Bk9R9_e0.js → CanvasWorkspace-D7ORj358.js} +1 -1
- package/client/dist/assets/DashboardPanel-BV7ybUDe.js +1 -0
- package/client/dist/assets/FileTree-5qfhBqdE.js +1 -0
- package/client/dist/assets/{GitPanel-RtyZUIWS.js → GitPanel-C_xFM-N2.js} +1 -1
- package/client/dist/assets/{LoginModal-BWep8a6g.js → LoginModal-CImJHRjX.js} +3 -3
- package/client/dist/assets/{MarkdownPreview-DHmk3qzu.js → MarkdownPreview-CESjI261.js} +1 -1
- package/client/dist/assets/{MermaidBlock-BuBc_G-F.js → MermaidBlock-BFM21cwe.js} +2 -2
- package/client/dist/assets/Onboarding-B3cteLu2.js +1 -0
- package/client/dist/assets/SetupForm-P6dsYgHO.js +1 -0
- package/client/dist/assets/WorkflowsPanel-CBoN80kc.js +1 -0
- package/client/dist/assets/index-46kkVu2i.css +1 -0
- package/client/dist/assets/{index-C5ptjuTl.js → index-HaY-3pK1.js} +20 -20
- package/client/dist/assets/{vendor-canvas-D39yWul6.js → vendor-canvas-DvHJ_Pn2.js} +1 -1
- package/client/dist/assets/{vendor-codemirror-CbtmxxaB.js → vendor-codemirror-D2ALgpaX.js} +1 -1
- package/client/dist/assets/{vendor-icons-BaD0x9SL.js → vendor-icons-GyYE35HP.js} +178 -138
- package/client/dist/assets/{vendor-mermaid-CH7SGc99.js → vendor-mermaid-DucWyDEe.js} +3 -3
- package/client/dist/assets/{vendor-syntax-DuHI9Ok6.js → vendor-syntax-LS_Nt30I.js} +1 -1
- package/client/dist/clear-cache.html +85 -85
- package/client/dist/index.html +17 -17
- package/client/dist/manifest.json +3 -3
- package/client/dist/mcp-docs.html +108 -108
- package/client/dist/offline.html +84 -84
- package/client/dist/sw.js +82 -82
- package/package.json +1 -1
- package/server/browser.js +131 -0
- package/server/database/db.js +102 -6
- package/server/index.js +27 -28
- package/server/middleware/auth.js +5 -2
- package/server/routes/browser.js +419 -0
- package/server/routes/projects.js +118 -19
- package/server/routes/vapi-chat.js +1 -1
- package/server/services/browser-ai.js +154 -0
- package/client/dist/assets/DashboardPanel-CblJfTGi.js +0 -1
- package/client/dist/assets/FileTree-BDUnBheV.js +0 -1
- package/client/dist/assets/Onboarding-Drnlt75a.js +0 -1
- package/client/dist/assets/SetupForm-CtCKitZG.js +0 -1
- package/client/dist/assets/WorkflowsPanel-B2mIXDvD.js +0 -1
- package/client/dist/assets/index-BFuqS0tY.css +0 -1
|
@@ -399,14 +399,8 @@ router.get('/clone-progress', async (req, res) => {
|
|
|
399
399
|
|
|
400
400
|
const IS_CLOUD_ENV = !!(process.env.RAILWAY_ENVIRONMENT || process.env.VERCEL || process.env.RENDER);
|
|
401
401
|
|
|
402
|
-
// Cloud mode: clone via relay on user's machine
|
|
402
|
+
// Cloud mode: clone via relay on user's machine, or sandbox if no relay
|
|
403
403
|
if (IS_CLOUD_ENV) {
|
|
404
|
-
if (!req.hasRelay || !req.hasRelay()) {
|
|
405
|
-
sendEvent('error', { message: 'Machine not connected. Run "uc connect" on your local machine.' });
|
|
406
|
-
res.end();
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
404
|
let githubToken = null;
|
|
411
405
|
if (githubTokenId) {
|
|
412
406
|
const token = await getGithubTokenById(parseInt(githubTokenId), req.user.id);
|
|
@@ -420,13 +414,10 @@ router.get('/clone-progress', async (req, res) => {
|
|
|
420
414
|
githubToken = newGithubToken;
|
|
421
415
|
}
|
|
422
416
|
|
|
423
|
-
sendEvent('progress', { message: 'Creating directory...' });
|
|
424
|
-
await req.sendRelay('create-folder', { folderPath: workspacePath }, 15000);
|
|
425
|
-
|
|
426
417
|
const normalizedUrl = githubUrl.replace(/\/+$/, '').replace(/\.git$/, '');
|
|
427
418
|
const repoName = normalizedUrl.split('/').pop() || 'repository';
|
|
428
|
-
const clonePath = `${workspacePath}/${repoName}`;
|
|
429
419
|
|
|
420
|
+
// Build authenticated clone URL
|
|
430
421
|
let cloneUrl = githubUrl;
|
|
431
422
|
if (githubToken) {
|
|
432
423
|
try {
|
|
@@ -439,19 +430,64 @@ router.get('/clone-progress', async (req, res) => {
|
|
|
439
430
|
}
|
|
440
431
|
}
|
|
441
432
|
|
|
442
|
-
|
|
433
|
+
// Option A: Relay connected — clone on user's machine
|
|
434
|
+
if (req.hasRelay && req.hasRelay()) {
|
|
435
|
+
const clonePath = `${workspacePath}/${repoName}`;
|
|
436
|
+
|
|
437
|
+
sendEvent('progress', { message: 'Creating directory...' });
|
|
438
|
+
await req.sendRelay('create-folder', { folderPath: workspacePath }, 15000);
|
|
439
|
+
|
|
440
|
+
sendEvent('progress', { message: `Cloning into '${repoName}'...` });
|
|
441
|
+
|
|
442
|
+
try {
|
|
443
|
+
await req.sendRelay('shell-command', {
|
|
444
|
+
command: `git clone "${cloneUrl}" "${clonePath}"`,
|
|
445
|
+
cwd: workspacePath
|
|
446
|
+
}, 120000);
|
|
447
|
+
|
|
448
|
+
const project = await addProjectManually(clonePath);
|
|
449
|
+
sendEvent('complete', { project, message: 'Repository cloned successfully' });
|
|
450
|
+
} catch (error) {
|
|
451
|
+
const sanitized = sanitizeGitError(error.message, githubToken);
|
|
452
|
+
sendEvent('error', { message: sanitized || 'Git clone failed' });
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
res.end();
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
443
458
|
|
|
459
|
+
// Option B: No relay — clone into per-user sandbox
|
|
444
460
|
try {
|
|
445
|
-
await
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
461
|
+
const { sandboxClient } = await import('../sandbox.js');
|
|
462
|
+
const sandboxAvailable = await sandboxClient.isAvailable();
|
|
463
|
+
if (!sandboxAvailable) {
|
|
464
|
+
sendEvent('error', { message: 'No machine connected and sandbox unavailable. Run "uc web connect" to connect your machine.' });
|
|
465
|
+
res.end();
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
449
468
|
|
|
450
|
-
const
|
|
451
|
-
sendEvent('
|
|
469
|
+
const userId = req.user.id;
|
|
470
|
+
sendEvent('progress', { message: 'Initializing sandbox...' });
|
|
471
|
+
await sandboxClient.initSandbox(userId);
|
|
472
|
+
|
|
473
|
+
const sandboxPath = `/workspace/${repoName}`;
|
|
474
|
+
sendEvent('progress', { message: `Cloning into '${repoName}' (sandbox)...` });
|
|
475
|
+
|
|
476
|
+
await sandboxClient.exec(userId, `git clone "${cloneUrl}" "${sandboxPath}"`, { timeout: 120000 });
|
|
477
|
+
|
|
478
|
+
sendEvent('progress', { message: 'Registering project...' });
|
|
479
|
+
|
|
480
|
+
// Save project with github_origin
|
|
481
|
+
const { projectDb } = await import('../database/db.js');
|
|
482
|
+
const project = await projectDb.upsert(userId, sandboxPath, repoName, githubUrl);
|
|
483
|
+
|
|
484
|
+
sendEvent('complete', {
|
|
485
|
+
project: { ...project, displayName: repoName, originalPath: sandboxPath, githubOrigin: githubUrl },
|
|
486
|
+
message: 'Repository cloned into sandbox'
|
|
487
|
+
});
|
|
452
488
|
} catch (error) {
|
|
453
489
|
const sanitized = sanitizeGitError(error.message, githubToken);
|
|
454
|
-
sendEvent('error', { message: sanitized || '
|
|
490
|
+
sendEvent('error', { message: sanitized || 'Sandbox clone failed' });
|
|
455
491
|
}
|
|
456
492
|
|
|
457
493
|
res.end();
|
|
@@ -652,4 +688,67 @@ function cloneGitHubRepository(githubUrl, destinationPath, githubToken = null) {
|
|
|
652
688
|
});
|
|
653
689
|
}
|
|
654
690
|
|
|
691
|
+
/**
|
|
692
|
+
* Push sandbox changes back to GitHub
|
|
693
|
+
* POST /api/projects/:projectName/push
|
|
694
|
+
*/
|
|
695
|
+
router.post('/:projectName/push', async (req, res) => {
|
|
696
|
+
const { branch, commitMessage } = req.body;
|
|
697
|
+
const userId = req.user.id;
|
|
698
|
+
|
|
699
|
+
try {
|
|
700
|
+
const { projectDb } = await import('../database/db.js');
|
|
701
|
+
const project = await projectDb.getByName(userId, req.params.projectName);
|
|
702
|
+
|
|
703
|
+
if (!project) {
|
|
704
|
+
return res.status(404).json({ error: 'Project not found' });
|
|
705
|
+
}
|
|
706
|
+
if (!project.github_origin) {
|
|
707
|
+
return res.status(400).json({ error: 'Not a GitHub project — no origin to push to' });
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// Get user's GitHub token
|
|
711
|
+
const { getDatabase } = await import('../database/db.js');
|
|
712
|
+
const db = await getDatabase();
|
|
713
|
+
const cred = await db.execute({
|
|
714
|
+
sql: 'SELECT credential_value FROM user_credentials WHERE user_id = ? AND credential_type = ? AND is_active = 1 LIMIT 1',
|
|
715
|
+
args: [userId, 'github_token']
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
const githubToken = cred.rows[0]?.credential_value;
|
|
719
|
+
if (!githubToken) {
|
|
720
|
+
return res.status(400).json({ error: 'No GitHub token configured. Add one in Settings > AI Providers.' });
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Set remote URL with token for auth
|
|
724
|
+
const originUrl = new URL(project.github_origin.endsWith('.git') ? project.github_origin : `${project.github_origin}.git`);
|
|
725
|
+
originUrl.username = githubToken;
|
|
726
|
+
originUrl.password = 'x-oauth-basic';
|
|
727
|
+
|
|
728
|
+
const { sandboxClient } = await import('../sandbox.js');
|
|
729
|
+
const cwd = project.original_path;
|
|
730
|
+
const targetBranch = branch || 'main';
|
|
731
|
+
const msg = commitMessage || 'Update from Upfyn Code';
|
|
732
|
+
|
|
733
|
+
// Set remote, stage, commit, push
|
|
734
|
+
await sandboxClient.exec(userId, `git remote set-url origin "${originUrl.toString()}"`, { cwd });
|
|
735
|
+
await sandboxClient.exec(userId, 'git add -A', { cwd });
|
|
736
|
+
|
|
737
|
+
try {
|
|
738
|
+
await sandboxClient.exec(userId, `git commit -m "${msg.replace(/"/g, '\\"')}"`, { cwd });
|
|
739
|
+
} catch {
|
|
740
|
+
return res.json({ success: true, message: 'No changes to commit' });
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
await sandboxClient.exec(userId, `git push origin ${targetBranch}`, { cwd, timeout: 60000 });
|
|
744
|
+
|
|
745
|
+
// Clean the token from the remote URL after push
|
|
746
|
+
await sandboxClient.exec(userId, `git remote set-url origin "${project.github_origin}"`, { cwd });
|
|
747
|
+
|
|
748
|
+
res.json({ success: true, message: `Pushed to ${targetBranch}` });
|
|
749
|
+
} catch (error) {
|
|
750
|
+
res.status(500).json({ error: error.message || 'Push failed' });
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
|
|
655
754
|
export default router;
|
|
@@ -488,7 +488,7 @@ async function handleTroubleshootConnection(metadata) {
|
|
|
488
488
|
connected: false,
|
|
489
489
|
message: 'Machine is NOT connected. Tell the user to open a terminal and run: uc connect',
|
|
490
490
|
troubleshooting: [
|
|
491
|
-
'Make sure upfynai-code is installed: npm install -g upfynai-code',
|
|
491
|
+
'Make sure upfynai-code is installed: npm install -g @upfynai-code/app',
|
|
492
492
|
'Run: uc connect',
|
|
493
493
|
'Check if their firewall is blocking WebSocket connections',
|
|
494
494
|
'Try: uc doctor — to diagnose issues',
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser AI Service — Stagehand integration for AI-driven browser automation.
|
|
3
|
+
* Lazy-loads @browserbasehq/stagehand (cloud-only dep, installed via nixpacks).
|
|
4
|
+
* Follows the composio.js pattern: lazy SDK, per-session instances, availability check.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
let Stagehand = null;
|
|
8
|
+
let sdkReady = null;
|
|
9
|
+
|
|
10
|
+
// Lazy-load Stagehand SDK (cloud-only dependency)
|
|
11
|
+
sdkReady = (async () => {
|
|
12
|
+
try {
|
|
13
|
+
const mod = await import('@browserbasehq/stagehand');
|
|
14
|
+
Stagehand = mod.Stagehand || mod.default;
|
|
15
|
+
} catch {
|
|
16
|
+
// SDK not installed — browser AI features unavailable (local installs)
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
19
|
+
|
|
20
|
+
// Per-session Stagehand instance cache
|
|
21
|
+
const instances = new Map();
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Check if the Stagehand SDK is available.
|
|
25
|
+
*/
|
|
26
|
+
async function isAvailable() {
|
|
27
|
+
await sdkReady;
|
|
28
|
+
return !!Stagehand;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get or create a Stagehand instance for a session.
|
|
33
|
+
*/
|
|
34
|
+
async function getOrCreate(sessionId, cdpUrl) {
|
|
35
|
+
if (instances.has(sessionId)) return instances.get(sessionId);
|
|
36
|
+
|
|
37
|
+
await sdkReady;
|
|
38
|
+
if (!Stagehand) throw new Error('Browser AI not available — Stagehand SDK not installed');
|
|
39
|
+
|
|
40
|
+
const stagehand = new Stagehand({
|
|
41
|
+
env: 'LOCAL',
|
|
42
|
+
enableCaching: true,
|
|
43
|
+
localBrowserLaunchOptions: {
|
|
44
|
+
cdpUrl,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
await stagehand.init();
|
|
48
|
+
|
|
49
|
+
instances.set(sessionId, stagehand);
|
|
50
|
+
return stagehand;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Execute a single AI action on the page.
|
|
55
|
+
* Chat mode: user says "click the login button" → this executes it.
|
|
56
|
+
*/
|
|
57
|
+
async function act(sessionId, cdpUrl, instruction) {
|
|
58
|
+
const stagehand = await getOrCreate(sessionId, cdpUrl);
|
|
59
|
+
const page = stagehand.page;
|
|
60
|
+
const result = await page.act({ action: instruction });
|
|
61
|
+
return { success: true, result, url: page.url() };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extract structured data from the current page.
|
|
66
|
+
*/
|
|
67
|
+
async function extract(sessionId, cdpUrl, instruction, schema) {
|
|
68
|
+
const stagehand = await getOrCreate(sessionId, cdpUrl);
|
|
69
|
+
const page = stagehand.page;
|
|
70
|
+
const opts = { instruction };
|
|
71
|
+
if (schema) opts.schema = schema;
|
|
72
|
+
const result = await page.extract(opts);
|
|
73
|
+
return { success: true, data: result };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Observe the current page — returns available actions/elements.
|
|
78
|
+
*/
|
|
79
|
+
async function observe(sessionId, cdpUrl, instruction) {
|
|
80
|
+
const stagehand = await getOrCreate(sessionId, cdpUrl);
|
|
81
|
+
const page = stagehand.page;
|
|
82
|
+
const opts = instruction ? { instruction } : {};
|
|
83
|
+
const result = await page.observe(opts);
|
|
84
|
+
return { success: true, observations: result };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Run an autonomous agent that pursues a goal across multiple steps.
|
|
89
|
+
* Streams each step to the onStep callback (for SSE).
|
|
90
|
+
*/
|
|
91
|
+
async function autonomousGoal(sessionId, cdpUrl, goal, maxSteps = 10, onStep) {
|
|
92
|
+
const stagehand = await getOrCreate(sessionId, cdpUrl);
|
|
93
|
+
const page = stagehand.page;
|
|
94
|
+
|
|
95
|
+
for (let step = 0; step < maxSteps; step++) {
|
|
96
|
+
try {
|
|
97
|
+
// Observe current state
|
|
98
|
+
const observations = await page.observe();
|
|
99
|
+
onStep({ step, type: 'observe', data: observations, url: page.url(), timestamp: Date.now() });
|
|
100
|
+
|
|
101
|
+
// Execute next action toward goal
|
|
102
|
+
const actionResult = await page.act({ action: `Working towards this goal: ${goal}` });
|
|
103
|
+
onStep({ step, type: 'act', data: actionResult, url: page.url(), timestamp: Date.now() });
|
|
104
|
+
|
|
105
|
+
// Check if done
|
|
106
|
+
const check = await page.extract({
|
|
107
|
+
instruction: `Has this goal been achieved: "${goal}"? Answer with done=true or done=false and a brief reason.`,
|
|
108
|
+
});
|
|
109
|
+
onStep({ step, type: 'check', data: check, timestamp: Date.now() });
|
|
110
|
+
|
|
111
|
+
if (check && check.done) break;
|
|
112
|
+
} catch (err) {
|
|
113
|
+
onStep({ step, type: 'error', message: err.message, timestamp: Date.now() });
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get console errors from the browser via CDP.
|
|
121
|
+
*/
|
|
122
|
+
async function getConsoleErrors(sessionId, cdpUrl) {
|
|
123
|
+
const stagehand = await getOrCreate(sessionId, cdpUrl);
|
|
124
|
+
const page = stagehand.page;
|
|
125
|
+
|
|
126
|
+
// Collect console errors using page.evaluate
|
|
127
|
+
const errors = await page.evaluate(() => {
|
|
128
|
+
// Check for any errors the page might have stored
|
|
129
|
+
return (window.__upfynErrors || []).slice(-50);
|
|
130
|
+
}).catch(() => []);
|
|
131
|
+
|
|
132
|
+
return errors;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Release a Stagehand instance for a session.
|
|
137
|
+
*/
|
|
138
|
+
async function release(sessionId) {
|
|
139
|
+
const instance = instances.get(sessionId);
|
|
140
|
+
if (instance) {
|
|
141
|
+
try { await instance.close(); } catch { /* ignore */ }
|
|
142
|
+
instances.delete(sessionId);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export {
|
|
147
|
+
isAvailable,
|
|
148
|
+
act,
|
|
149
|
+
extract,
|
|
150
|
+
observe,
|
|
151
|
+
autonomousGoal,
|
|
152
|
+
getConsoleErrors,
|
|
153
|
+
release,
|
|
154
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as o,j as e}from"./vendor-react-96lCPsRK.js";import{d as C,I as j}from"./index-C5ptjuTl.js";import{u as M,a as T}from"./AppContent-Bvg0CPCO.js";import{ab as $,R as A,M as L,Z as I,b9 as R,h as _,bi as D,t as U,at as E,aB as V,v as B,bj as F}from"./vendor-icons-BaD0x9SL.js";import"./vendor-syntax-DuHI9Ok6.js";import"./vendor-markdown-CimbIo6Y.js";import"./vendor-i18n-DCFGyhQR.js";import"./LoginModal-BWep8a6g.js";import"./vendor-xterm-CZq1hqo1.js";import"./vendor-canvas-D39yWul6.js";import"./vendor-mermaid-CH7SGc99.js";import"./vendor-codemirror-CbtmxxaB.js";function O({onRefresh:t,threshold:r=80,maxPull:i=120,enabled:s=!0}){const d=o.useRef(0),[n,c]=o.useState(0),[m,f]=o.useState(!1),u=o.useRef(!1),w=o.useCallback(l=>{!s||m||(d.current=l.touches[0].clientY,u.current=!1)},[s,m]),h=o.useCallback(l=>{if(!s||m||l.currentTarget.scrollTop>0)return;const b=l.touches[0].clientY-d.current;b>0&&(u.current=!0,c(Math.min(b*.5,i)))},[s,m,i]),x=o.useCallback(async()=>{if(u.current){if(n>=r){f(!0);try{await t()}finally{f(!1)}}c(0),u.current=!1}},[n,r,t]);return{pullDistance:n,isRefreshing:m,handlers:{onTouchStart:w,onTouchMove:h,onTouchEnd:x}}}function S({className:t}){return e.jsx("div",{className:`animate-pulse rounded-md bg-muted/60 ${t||""}`})}function ee({selectedProject:t}){var k;const[r,i]=o.useState(null),[s,d]=o.useState(null),[n,c]=o.useState(!0),[m,f]=o.useState(null),{canPrompt:u,promptInstall:w}=M(),{isMobile:h}=T({trackPWA:!1}),x=o.useCallback(async()=>{c(!0),f(null);try{const a=await C("/api/dashboard/stats");if(a.ok){const g=await a.json();i(g)}}catch{}if(j)try{const a=await C("/api/vapi/usage");if(a.ok){const g=await a.json();d(g)}}catch{}c(!1)},[]),{pullDistance:l,isRefreshing:y,handlers:b}=O({onRefresh:x,enabled:h});return o.useEffect(()=>{x()},[x]),e.jsxs("div",{className:"h-full overflow-y-auto p-4 sm:p-6 space-y-6","data-pull-refresh":!0,...h?b:{},style:l>0?{transform:`translateY(${l*.3}px)`}:void 0,children:[h&&(l>0||y)&&e.jsx("div",{className:"flex items-center justify-center py-2 -mt-2",children:y?e.jsx("div",{className:"w-5 h-5 border-2 border-primary/30 border-t-primary rounded-full animate-spin"}):e.jsx("svg",{className:"w-5 h-5 text-muted-foreground transition-transform",style:{transform:`rotate(${Math.min(l/80*180,180)}deg)`},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[e.jsx($,{className:"w-5 h-5 text-blue-500"}),"Dashboard"]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:t?`Project: ${t.displayName||t.name}`:"Overview"})]}),e.jsx("button",{onClick:x,disabled:n,className:"p-2 rounded-lg hover:bg-muted/60 text-muted-foreground hover:text-foreground transition-colors",title:"Refresh stats",children:e.jsx(A,{className:`w-4 h-4 ${n?"animate-spin":""}`})})]}),e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-3",children:[e.jsx(N,{icon:L,label:"Sessions",value:(r==null?void 0:r.total)??0,subtext:r!=null&&r.today?`${r.today} today`:void 0,color:"blue",loading:n}),e.jsx(N,{icon:I,label:"AI Providers",value:r!=null&&r.providers?Object.keys(r.providers).length:0,subtext:r!=null&&r.providers?Object.keys(r.providers).join(", "):void 0,color:"purple",loading:n}),j&&e.jsxs(e.Fragment,{children:[e.jsx(N,{icon:R,label:"Voice Calls",value:((k=s==null?void 0:s.allTime)==null?void 0:k.calls)??0,subtext:s!=null&&s.today?`${s.today.calls} today`:void 0,color:"amber",loading:n}),e.jsx(N,{icon:_,label:"Call Limit",value:(s==null?void 0:s.remaining)!=null?`${s.remaining} left`:0,subtext:s!=null&&s.limit?`of ${s.limit}/day`:void 0,color:"emerald",loading:n})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-muted-foreground mb-3 uppercase tracking-wider",children:"Quick Actions"}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2",children:[e.jsx(v,{label:"Install CLI",description:"npm install -g upfynai-code",onClick:()=>navigator.clipboard.writeText("npm install -g upfynai-code")}),e.jsx(v,{label:"Connect Machine",description:"uc connect",onClick:()=>navigator.clipboard.writeText("uc connect")}),j&&e.jsx(v,{label:"View Pricing",description:"Upgrade your plan",href:"https://cli.upfyn.com/pricing"}),u&&e.jsx(v,{label:"Install App",description:"Add Upfyn to your home screen",onClick:w})]})]}),j&&(s==null?void 0:s.recentCalls)&&s.recentCalls.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-muted-foreground mb-3 uppercase tracking-wider",children:"Recent Voice Calls"}),e.jsx("div",{className:"space-y-2",children:s.recentCalls.slice(0,5).map((a,g)=>e.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg bg-muted/30 border border-border/50",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx(R,{className:"w-4 h-4 text-amber-500 flex-shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm text-foreground truncate",children:a.summary||`Voice call — ${Math.round(a.duration_seconds||0)}s`}),e.jsx("p",{className:"text-xs text-muted-foreground",children:a.created_at?new Date(a.created_at).toLocaleString():"Unknown time"})]})]}),e.jsx("span",{className:`text-xs px-2 py-0.5 rounded-full ${a.status==="completed"?"bg-emerald-500/10 text-emerald-400":a.status==="ended"?"bg-blue-500/10 text-blue-400":"bg-muted text-muted-foreground"}`,children:a.status||"unknown"})]},a.vapi_call_id||g))})]}),t&&e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-muted-foreground mb-3 uppercase tracking-wider",children:"Project Info"}),e.jsxs("div",{className:"rounded-lg bg-muted/30 border border-border/50 p-4 space-y-2",children:[e.jsx(p,{label:"Name",value:t.displayName||t.name}),e.jsx(p,{label:"Path",value:t.fullPath||t.path||"—"}),t.sessions&&e.jsx(p,{label:"Claude Sessions",value:String(t.sessions.length)}),t.cursorSessions&&e.jsx(p,{label:"Cursor Sessions",value:String(t.cursorSessions.length)}),t.codexSessions&&e.jsx(p,{label:"Codex Sessions",value:String(t.codexSessions.length)})]})]}),!t&&e.jsxs("div",{children:[e.jsxs("h3",{className:"text-sm font-medium text-muted-foreground mb-3 uppercase tracking-wider flex items-center gap-2",children:[e.jsx(D,{className:"w-3.5 h-3.5"}),"Getting Started"]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{className:"rounded-lg border border-border/50 bg-card/50 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(U,{className:"w-4 h-4 text-blue-500"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"1. Install the CLI"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-2",children:["Install globally, then run ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"uc"})," to launch."]}),e.jsx("code",{className:"text-xs bg-muted/50 px-2 py-1 rounded block text-foreground/80",children:"npm install -g upfynai-code"})]}),e.jsxs("div",{className:"rounded-lg border border-border/50 bg-card/50 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(I,{className:"w-4 h-4 text-yellow-500"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"2. Connect Your Machine"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:"Bridge your local dev environment to this web UI."}),e.jsx("code",{className:"text-xs bg-muted/50 px-2 py-1 rounded block text-foreground/80",children:"uc connect --key your_relay_token"})]}),e.jsxs("div",{className:"rounded-lg border border-border/50 bg-card/50 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(E,{className:"w-4 h-4 text-indigo-500"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"3. Use the Canvas"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Switch to the Canvas tab to create visual workspaces with code blocks, diagrams, and notes."})]}),e.jsxs("div",{className:"rounded-lg border border-border/50 bg-card/50 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(V,{className:"w-4 h-4 text-emerald-500"}),e.jsx("span",{className:"text-sm font-medium text-foreground",children:"4. Chat with AI"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Use the Chat tab to talk to Claude, Cursor, or Codex. Bring your own API keys in Settings."})]})]})]})]})}function N({icon:t,label:r,value:i,subtext:s,color:d,loading:n}){const c={blue:"text-blue-500 bg-blue-500/10",purple:"text-purple-500 bg-purple-500/10",amber:"text-amber-500 bg-amber-500/10",emerald:"text-emerald-500 bg-emerald-500/10"};return e.jsxs("div",{className:"rounded-lg border border-border/50 bg-card/50 p-3 sm:p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("div",{className:`w-7 h-7 rounded-md flex items-center justify-center ${c[d]}`,children:e.jsx(t,{className:"w-3.5 h-3.5"})}),e.jsx("span",{className:"text-xs text-muted-foreground",children:r})]}),n?e.jsxs(e.Fragment,{children:[e.jsx(S,{className:"h-6 w-16 mb-1"}),e.jsx(S,{className:"h-3 w-20"})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-xl font-semibold text-foreground",children:i}),s&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:s})]})]})}function v({label:t,description:r,onClick:i,href:s}){const d=s?"a":"button",n=s?{href:s,target:"_blank",rel:"noopener noreferrer"}:{onClick:i};return e.jsxs(d,{...n,className:"flex items-center justify-between p-3 rounded-lg border border-border/50 bg-card/50 hover:bg-muted/60 transition-colors text-left group",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:t}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r})]}),s?e.jsx(B,{className:"w-3.5 h-3.5 text-muted-foreground group-hover:text-foreground"}):e.jsx(F,{className:"w-3.5 h-3.5 text-muted-foreground group-hover:text-foreground"})]})}function p({label:t,value:r}){return e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:t}),e.jsx("span",{className:"text-foreground font-mono text-xs truncate max-w-[60%] text-right",children:r})]})}export{ee as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as x,j as e,R as Ee}from"./vendor-react-96lCPsRK.js";import{B as V,I as Ie,S as Fe,c as h}from"./AppContent-Bvg0CPCO.js";import{d as Te,b as Le}from"./index-C5ptjuTl.js";import{X as ye,a6 as Me,E as ze,aw as Ae,e as xe,n as me,q as De,m as Re,ax as y,ay as U,$ as I,az as J,aA as Y,aB as ee,S as a,aC as $,aD as F,aE as oe,aF as T,t as j,aG as te,y as w,aH as G,aI as je,aJ as C,aK as S,aL as A,aM as D,aN as E,aO as Be,aP as b,aQ as pe,aR as Oe,aS as ue,aT as R,aU as B,A as ge,aV as Ve,aW as Ue,aX as O,aY as fe,aZ as $e,a_ as Ge,ae as Z}from"./vendor-icons-BaD0x9SL.js";import{u as qe}from"./LoginModal-BWep8a6g.js";import"./vendor-syntax-DuHI9Ok6.js";import"./vendor-markdown-CimbIo6Y.js";import"./vendor-codemirror-CbtmxxaB.js";import"./vendor-i18n-DCFGyhQR.js";import"./vendor-xterm-CZq1hqo1.js";import"./vendor-canvas-D39yWul6.js";import"./vendor-mermaid-CH7SGc99.js";function _e({file:i,onClose:u}){const d=`/api/projects/${i.projectName}/files/content?path=${encodeURIComponent(i.path)}`,[s,p]=x.useState(null),[L,q]=x.useState(null),[N,g]=x.useState(!0);return x.useEffect(()=>{let f;const M=new AbortController;return(async()=>{try{g(!0),q(null),p(null);const m=await Te(d,{signal:M.signal});if(!m.ok)throw new Error(`Request failed with status ${m.status}`);const _=await m.blob();f=URL.createObjectURL(_),p(f)}catch(m){if(m.name==="AbortError")return;console.error("Error loading image:",m),q("Unable to load image")}finally{g(!1)}})(),()=>{M.abort(),f&&URL.revokeObjectURL(f)}},[d]),e.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-4xl max-h-[90vh] w-full mx-4 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:i.name}),e.jsx(V,{variant:"ghost",size:"sm",onClick:u,className:"h-8 w-8 p-0",children:e.jsx(ye,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"p-4 flex justify-center items-center bg-gray-50 dark:bg-gray-900 min-h-[400px]",children:[N&&e.jsx("div",{className:"text-center text-gray-500 dark:text-gray-400",children:e.jsx("p",{children:"Loading image…"})}),!N&&s&&e.jsx("img",{src:s,alt:i.name,className:"max-w-full max-h-[70vh] object-contain rounded-lg shadow-md"}),!N&&!s&&e.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[e.jsx("p",{children:L||"Unable to load image"}),e.jsx("p",{className:"text-sm mt-2 break-all",children:i.path})]})]}),e.jsx("div",{className:"p-4 border-t bg-gray-50 dark:bg-gray-800",children:e.jsx("p",{className:"text-sm text-gray-600 dark:text-gray-400",children:i.path})})]})})}const He="w-4 h-4 flex-shrink-0",he={js:{icon:R,color:"text-yellow-500"},jsx:{icon:R,color:"text-yellow-500"},mjs:{icon:R,color:"text-yellow-500"},cjs:{icon:R,color:"text-yellow-500"},ts:{icon:B,color:"text-blue-500"},tsx:{icon:B,color:"text-blue-500"},mts:{icon:B,color:"text-blue-500"},py:{icon:Z,color:"text-emerald-500"},pyw:{icon:Z,color:"text-emerald-500"},pyi:{icon:Z,color:"text-emerald-400"},ipynb:{icon:Ge,color:"text-orange-500"},rs:{icon:$,color:"text-orange-600"},toml:{icon:a,color:"text-gray-500"},go:{icon:U,color:"text-cyan-500"},rb:{icon:te,color:"text-red-500"},erb:{icon:te,color:"text-red-400"},php:{icon:$e,color:"text-violet-500"},java:{icon:fe,color:"text-red-600"},jar:{icon:fe,color:"text-red-500"},kt:{icon:U,color:"text-violet-500"},kts:{icon:U,color:"text-violet-400"},c:{icon:O,color:"text-blue-600"},h:{icon:O,color:"text-blue-400"},cpp:{icon:O,color:"text-blue-700"},hpp:{icon:O,color:"text-blue-500"},cc:{icon:O,color:"text-blue-700"},cs:{icon:U,color:"text-purple-600"},swift:{icon:oe,color:"text-orange-500"},lua:{icon:Ue,color:"text-blue-500"},r:{icon:Ve,color:"text-blue-600"},html:{icon:ge,color:"text-orange-600"},htm:{icon:ge,color:"text-orange-600"},css:{icon:F,color:"text-blue-500"},scss:{icon:F,color:"text-pink-500"},sass:{icon:F,color:"text-pink-400"},less:{icon:F,color:"text-indigo-500"},vue:{icon:B,color:"text-emerald-500"},svelte:{icon:B,color:"text-orange-500"},json:{icon:T,color:"text-yellow-600"},jsonc:{icon:T,color:"text-yellow-500"},json5:{icon:T,color:"text-yellow-500"},yaml:{icon:a,color:"text-purple-400"},yml:{icon:a,color:"text-purple-400"},xml:{icon:R,color:"text-orange-500"},csv:{icon:ue,color:"text-green-600"},tsv:{icon:ue,color:"text-green-500"},sql:{icon:Oe,color:"text-blue-500"},graphql:{icon:pe,color:"text-pink-500"},gql:{icon:pe,color:"text-pink-500"},proto:{icon:G,color:"text-green-500"},env:{icon:w,color:"text-yellow-600"},md:{icon:ee,color:"text-blue-500"},mdx:{icon:ee,color:"text-blue-400"},txt:{icon:I,color:"text-gray-500"},doc:{icon:I,color:"text-blue-600"},docx:{icon:I,color:"text-blue-600"},pdf:{icon:Y,color:"text-red-600"},rtf:{icon:I,color:"text-gray-500"},tex:{icon:J,color:"text-teal-600"},rst:{icon:I,color:"text-gray-400"},sh:{icon:j,color:"text-green-500"},bash:{icon:j,color:"text-green-500"},zsh:{icon:j,color:"text-green-400"},fish:{icon:j,color:"text-green-400"},ps1:{icon:j,color:"text-blue-400"},bat:{icon:j,color:"text-gray-500"},cmd:{icon:j,color:"text-gray-500"},png:{icon:b,color:"text-purple-500"},jpg:{icon:b,color:"text-purple-500"},jpeg:{icon:b,color:"text-purple-500"},gif:{icon:b,color:"text-purple-400"},webp:{icon:b,color:"text-purple-400"},ico:{icon:b,color:"text-purple-400"},bmp:{icon:b,color:"text-purple-400"},tiff:{icon:b,color:"text-purple-400"},svg:{icon:Be,color:"text-amber-500"},mp3:{icon:E,color:"text-pink-500"},wav:{icon:E,color:"text-pink-500"},ogg:{icon:E,color:"text-pink-400"},flac:{icon:E,color:"text-pink-400"},aac:{icon:E,color:"text-pink-400"},m4a:{icon:E,color:"text-pink-400"},mp4:{icon:D,color:"text-rose-500"},mov:{icon:D,color:"text-rose-500"},avi:{icon:D,color:"text-rose-500"},webm:{icon:D,color:"text-rose-400"},mkv:{icon:D,color:"text-rose-400"},ttf:{icon:A,color:"text-red-500"},otf:{icon:A,color:"text-red-500"},woff:{icon:A,color:"text-red-400"},woff2:{icon:A,color:"text-red-400"},eot:{icon:A,color:"text-red-400"},zip:{icon:S,color:"text-amber-600"},tar:{icon:S,color:"text-amber-600"},gz:{icon:S,color:"text-amber-600"},bz2:{icon:S,color:"text-amber-600"},rar:{icon:S,color:"text-amber-500"},"7z":{icon:S,color:"text-amber-500"},lock:{icon:y,color:"text-gray-500"},exe:{icon:C,color:"text-gray-500"},bin:{icon:C,color:"text-gray-500"},dll:{icon:C,color:"text-gray-400"},so:{icon:C,color:"text-gray-400"},dylib:{icon:C,color:"text-gray-400"},wasm:{icon:C,color:"text-purple-500"},ini:{icon:a,color:"text-gray-500"},cfg:{icon:a,color:"text-gray-500"},conf:{icon:a,color:"text-gray-500"},log:{icon:J,color:"text-gray-400"},map:{icon:je,color:"text-gray-400"}},be={Dockerfile:{icon:G,color:"text-blue-500"},"docker-compose.yml":{icon:G,color:"text-blue-500"},"docker-compose.yaml":{icon:G,color:"text-blue-500"},".dockerignore":{icon:G,color:"text-gray-500"},".gitignore":{icon:a,color:"text-gray-500"},".gitmodules":{icon:a,color:"text-gray-500"},".gitattributes":{icon:a,color:"text-gray-500"},".editorconfig":{icon:a,color:"text-gray-500"},".prettierrc":{icon:a,color:"text-pink-400"},".prettierignore":{icon:a,color:"text-gray-500"},".eslintrc":{icon:a,color:"text-violet-500"},".eslintrc.js":{icon:a,color:"text-violet-500"},".eslintrc.json":{icon:a,color:"text-violet-500"},".eslintrc.cjs":{icon:a,color:"text-violet-500"},"eslint.config.js":{icon:a,color:"text-violet-500"},"eslint.config.mjs":{icon:a,color:"text-violet-500"},".env":{icon:w,color:"text-yellow-600"},".env.local":{icon:w,color:"text-yellow-600"},".env.development":{icon:w,color:"text-yellow-500"},".env.production":{icon:w,color:"text-yellow-600"},".env.example":{icon:w,color:"text-yellow-400"},"package.json":{icon:T,color:"text-green-500"},"package-lock.json":{icon:y,color:"text-gray-500"},"yarn.lock":{icon:y,color:"text-blue-400"},"pnpm-lock.yaml":{icon:y,color:"text-orange-400"},"bun.lockb":{icon:y,color:"text-gray-400"},"Cargo.toml":{icon:$,color:"text-orange-600"},"Cargo.lock":{icon:y,color:"text-orange-400"},Gemfile:{icon:te,color:"text-red-500"},"Gemfile.lock":{icon:y,color:"text-red-400"},Makefile:{icon:j,color:"text-gray-500"},"CMakeLists.txt":{icon:$,color:"text-blue-500"},"tsconfig.json":{icon:T,color:"text-blue-500"},"jsconfig.json":{icon:T,color:"text-yellow-500"},"vite.config.ts":{icon:oe,color:"text-purple-500"},"vite.config.js":{icon:oe,color:"text-purple-500"},"webpack.config.js":{icon:$,color:"text-blue-500"},"tailwind.config.js":{icon:F,color:"text-cyan-500"},"tailwind.config.ts":{icon:F,color:"text-cyan-500"},"postcss.config.js":{icon:$,color:"text-red-400"},"babel.config.js":{icon:a,color:"text-yellow-500"},".babelrc":{icon:a,color:"text-yellow-500"},"README.md":{icon:ee,color:"text-blue-500"},LICENSE:{icon:Y,color:"text-gray-500"},"LICENSE.md":{icon:Y,color:"text-gray-500"},"CHANGELOG.md":{icon:J,color:"text-blue-400"},"requirements.txt":{icon:I,color:"text-emerald-400"},"go.mod":{icon:U,color:"text-cyan-500"},"go.sum":{icon:y,color:"text-cyan-400"}};function We(i){var d;if(be[i])return be[i];if(i.startsWith(".env"))return{icon:w,color:"text-yellow-600"};const u=(d=i.split(".").pop())==null?void 0:d.toLowerCase();return u&&he[u]?he[u]:{icon:je,color:"text-muted-foreground"}}function no({selectedProject:i,onFileOpen:u,activeFilePath:d=null}){const{t:s}=qe(),[p,L]=x.useState([]),[q,N]=x.useState(!1),[g,f]=x.useState(new Set),[M,W]=x.useState(null),[m,_]=x.useState("detailed"),[v,re]=x.useState(""),[z,ce]=x.useState([]),H=Ee.useRef(null);x.useEffect(()=>{i&&we()},[i]),x.useEffect(()=>{const t=localStorage.getItem("file-tree-view-mode");t&&["simple","detailed","compact"].includes(t)&&_(t)},[]),x.useEffect(()=>{if(!d||p.length===0)return;const t=d.replace(/\\/g,"/"),c=(r,l,n=[])=>{for(const k of r){const ie=(k.path||"").replace(/\\/g,"/");if(k.type==="directory"&&k.children){const Se=[...n,k.path];if(t.startsWith(ie+"/")){const de=c(k.children,l,Se);if(de)return de}}if(k.type!=="directory"&&ie===t)return n}return null},o=c(p,t);o&&o.length>0&&f(r=>{const l=new Set(r);return o.forEach(n=>l.add(n)),l}),requestAnimationFrame(()=>{var r;(r=H.current)==null||r.scrollIntoView({block:"nearest",behavior:"smooth"})})},[d,p]),x.useEffect(()=>{if(!v.trim())ce(p);else{const t=ne(p,v.toLowerCase());ce(t);const c=o=>{o.forEach(r=>{r.type==="directory"&&r.children&&r.children.length>0&&(f(l=>new Set(l.add(r.path))),c(r.children))})};c(t)}},[p,v]);const ne=(t,c)=>t.reduce((o,r)=>{const l=r.name.toLowerCase().includes(c);let n=[];return r.type==="directory"&&r.children&&(n=ne(r.children,c)),(l||n.length>0)&&o.push({...r,children:n}),o},[]),we=async()=>{N(!0);try{const t=await Le.getFiles(i.name);if(!t.ok){const o=await t.text();console.error("❌ File fetch failed:",t.status,o),L([]);return}const c=await t.json();L(c)}catch(t){console.error("❌ Error fetching files:",t),L([])}finally{N(!1)}},Ne=t=>{const c=new Set(g);c.has(t)?c.delete(t):c.add(t),f(c)},P=t=>{_(t),localStorage.setItem("file-tree-view-mode",t)},Q=t=>{if(!t||t===0)return"0 B";const c=1024,o=["B","KB","MB","GB"],r=Math.floor(Math.log(t)/Math.log(c));return parseFloat((t/Math.pow(c,r)).toFixed(1))+" "+o[r]},ve=t=>{if(!t)return"-";const c=new Date,o=new Date(t),r=Math.floor((c-o)/1e3);return r<60?s("fileTree.justNow"):r<3600?s("fileTree.minAgo",{count:Math.floor(r/60)}):r<86400?s("fileTree.hoursAgo",{count:Math.floor(r/3600)}):r<2592e3?s("fileTree.daysAgo",{count:Math.floor(r/86400)}):o.toLocaleDateString()},ke=t=>{var r;const c=(r=t.split(".").pop())==null?void 0:r.toLowerCase();return["png","jpg","jpeg","gif","svg","webp","ico","bmp"].includes(c)},Ce=t=>{const{icon:c,color:o}=We(t);return e.jsx(c,{className:h(He,o)})},X=t=>{t.type==="directory"?Ne(t.path):ke(t.name)?W({name:t.name,path:t.path,projectPath:i.path,projectName:i.name}):u&&u(t.path)},K=t=>{const c=t.type==="directory",o=g.has(t.path);return c?e.jsxs("span",{className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx(De,{className:h("w-3.5 h-3.5 text-muted-foreground/70 transition-transform duration-150",o&&"rotate-90")}),o?e.jsx(Re,{className:"w-4 h-4 text-blue-500 flex-shrink-0"}):e.jsx(me,{className:"w-4 h-4 text-muted-foreground flex-shrink-0"})]}):e.jsx("span",{className:"flex items-center flex-shrink-0 ml-[18px]",children:Ce(t.name)})},se=(t,c=0)=>t.map(o=>{const r=o.type==="directory",l=r&&g.has(o.path),n=!r&&d&&(o.path||"").replace(/\\/g,"/")===d.replace(/\\/g,"/");return e.jsxs("div",{className:"select-none",children:[e.jsxs("div",{ref:n?H:void 0,className:h("group flex items-center gap-1.5 py-[3px] pr-2 cursor-pointer rounded-sm","hover:bg-accent/60 transition-colors duration-100",n&&"bg-primary/10 border-l-2 !border-primary font-medium",!n&&r&&l&&"border-l-2 border-primary/30",!n&&r&&!l&&"border-l-2 border-transparent",!n&&!r&&"border-l-2 border-transparent"),style:{paddingLeft:`${c*16+4}px`},onClick:()=>X(o),children:[K(o),e.jsx("span",{className:h("text-[13px] leading-tight truncate",n?"font-medium text-primary":r?"font-medium text-foreground":"text-foreground/90"),children:o.name})]}),r&&l&&o.children&&o.children.length>0&&e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"absolute top-0 bottom-0 border-l border-border/40",style:{left:`${c*16+14}px`},"aria-hidden":"true"}),se(o.children,c+1)]})]},o.path)}),le=(t,c=0)=>t.map(o=>{const r=o.type==="directory",l=r&&g.has(o.path),n=!r&&d&&(o.path||"").replace(/\\/g,"/")===d.replace(/\\/g,"/");return e.jsxs("div",{className:"select-none",children:[e.jsxs("div",{ref:n?H:void 0,className:h("group grid grid-cols-1 sm:grid-cols-12 gap-0 sm:gap-2 py-[3px] pr-2 hover:bg-accent/60 cursor-pointer items-center rounded-sm transition-colors duration-100",n&&"bg-primary/10 border-l-2 !border-primary font-medium",!n&&r&&l&&"border-l-2 border-primary/30",!n&&r&&!l&&"border-l-2 border-transparent",!n&&!r&&"border-l-2 border-transparent"),style:{paddingLeft:`${c*16+4}px`},onClick:()=>X(o),children:[e.jsxs("div",{className:"sm:col-span-5 flex items-center gap-1.5 min-w-0",children:[K(o),e.jsx("span",{className:h("text-[13px] leading-tight truncate",n?"font-medium text-primary":r?"font-medium text-foreground":"text-foreground/90"),children:o.name}),o.type==="file"&&o.size!=null&&e.jsx("span",{className:"sm:hidden text-[10px] text-muted-foreground/60 ml-auto flex-shrink-0",children:Q(o.size)})]}),e.jsx("div",{className:"hidden sm:block sm:col-span-2 text-sm text-muted-foreground tabular-nums",children:o.type==="file"?Q(o.size):""}),e.jsx("div",{className:"hidden sm:block sm:col-span-3 text-sm text-muted-foreground",children:ve(o.modified)}),e.jsx("div",{className:"hidden sm:block sm:col-span-2 text-sm text-muted-foreground font-mono",children:o.permissionsRwx||""})]}),r&&l&&o.children&&e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"absolute top-0 bottom-0 border-l border-border/40",style:{left:`${c*16+14}px`},"aria-hidden":"true"}),le(o.children,c+1)]})]},o.path)}),ae=(t,c=0)=>t.map(o=>{const r=o.type==="directory",l=r&&g.has(o.path),n=!r&&d&&(o.path||"").replace(/\\/g,"/")===d.replace(/\\/g,"/");return e.jsxs("div",{className:"select-none",children:[e.jsxs("div",{ref:n?H:void 0,className:h("group flex items-center justify-between py-[3px] pr-2 hover:bg-accent/60 cursor-pointer rounded-sm transition-colors duration-100",n&&"bg-primary/10 border-l-2 !border-primary font-medium",!n&&r&&l&&"border-l-2 border-primary/30",!n&&r&&!l&&"border-l-2 border-transparent",!n&&!r&&"border-l-2 border-transparent"),style:{paddingLeft:`${c*16+4}px`},onClick:()=>X(o),children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[K(o),e.jsx("span",{className:h("text-[13px] leading-tight truncate",n?"font-medium text-primary":r?"font-medium text-foreground":"text-foreground/90"),children:o.name})]}),e.jsx("div",{className:"flex items-center gap-3 text-sm text-muted-foreground flex-shrink-0 ml-2",children:o.type==="file"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"tabular-nums",children:Q(o.size)}),e.jsx("span",{className:"font-mono",children:o.permissionsRwx})]})})]}),r&&l&&o.children&&e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"absolute top-0 bottom-0 border-l border-border/40",style:{left:`${c*16+14}px`},"aria-hidden":"true"}),ae(o.children,c+1)]})]},o.path)});return q?e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsx("div",{className:"text-muted-foreground text-sm",children:s("fileTree.loading")})}):e.jsxs("div",{className:"h-full flex flex-col bg-background",children:[e.jsxs("div",{className:"px-3 pt-3 pb-2 border-b border-border space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-medium text-foreground",children:s("fileTree.files")}),e.jsxs("div",{className:"flex gap-0.5",children:[e.jsx(V,{variant:m==="simple"?"default":"ghost",size:"sm",className:"h-7 w-7 p-0",onClick:()=>P("simple"),title:s("fileTree.simpleView"),children:e.jsx(Me,{className:"w-3.5 h-3.5"})}),e.jsx(V,{variant:m==="compact"?"default":"ghost",size:"sm",className:"h-7 w-7 p-0",onClick:()=>P("compact"),title:s("fileTree.compactView"),children:e.jsx(ze,{className:"w-3.5 h-3.5"})}),e.jsx(V,{variant:m==="detailed"?"default":"ghost",size:"sm",className:"h-7 w-7 p-0",onClick:()=>P("detailed"),title:s("fileTree.detailedView"),children:e.jsx(Ae,{className:"w-3.5 h-3.5"})})]})]}),e.jsxs("div",{className:"relative",children:[e.jsx(xe,{className:"absolute left-2 top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground"}),e.jsx(Ie,{type:"text",placeholder:s("fileTree.searchPlaceholder"),value:v,onChange:t=>re(t.target.value),className:"pl-8 pr-8 h-8 text-sm"}),v&&e.jsx(V,{variant:"ghost",size:"sm",className:"absolute right-0.5 top-1/2 transform -translate-y-1/2 h-5 w-5 p-0 hover:bg-accent",onClick:()=>re(""),title:s("fileTree.clearSearch"),children:e.jsx(ye,{className:"w-3 h-3"})})]})]}),m==="detailed"&&z.length>0&&e.jsx("div",{className:"px-3 pt-1.5 pb-1 border-b border-border",children:e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-12 gap-2 px-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70",children:[e.jsx("div",{className:"sm:col-span-5",children:s("fileTree.name")}),e.jsx("div",{className:"hidden sm:block sm:col-span-2",children:s("fileTree.size")}),e.jsx("div",{className:"hidden sm:block sm:col-span-3",children:s("fileTree.modified")}),e.jsx("div",{className:"hidden sm:block sm:col-span-2",children:s("fileTree.permissions")})]})}),e.jsx(Fe,{className:"flex-1 px-2 py-1",children:p.length===0?e.jsxs("div",{className:"text-center py-8",children:[e.jsx("div",{className:"w-12 h-12 bg-muted rounded-lg flex items-center justify-center mx-auto mb-3",children:e.jsx(me,{className:"w-6 h-6 text-muted-foreground"})}),e.jsx("h4",{className:"font-medium text-foreground mb-1",children:s("fileTree.noFilesFound")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("fileTree.checkProjectPath")})]}):z.length===0&&v?e.jsxs("div",{className:"text-center py-8",children:[e.jsx("div",{className:"w-12 h-12 bg-muted rounded-lg flex items-center justify-center mx-auto mb-3",children:e.jsx(xe,{className:"w-6 h-6 text-muted-foreground"})}),e.jsx("h4",{className:"font-medium text-foreground mb-1",children:s("fileTree.noMatchesFound")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("fileTree.tryDifferentSearch")})]}):e.jsxs("div",{children:[m==="simple"&&se(z),m==="compact"&&ae(z),m==="detailed"&&le(z)]})}),M&&e.jsx(_e,{file:M,onClose:()=>W(null)})]})}export{no as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r,j as e}from"./vendor-react-96lCPsRK.js";import{L as X,b as ee,C as te,a as se}from"./LoginModal-BWep8a6g.js";import{I as ae,h as re,d as c}from"./index-C5ptjuTl.js";import{b as ie,t as ne,at as oe,Z as le,G as de,au as ce,av as ue,j as me,r as xe,L as $,a4 as O,q as ge}from"./vendor-icons-BaD0x9SL.js";import"./vendor-xterm-CZq1hqo1.js";import"./vendor-canvas-D39yWul6.js";import"./vendor-mermaid-CH7SGc99.js";import"./vendor-syntax-DuHI9Ok6.js";import"./vendor-markdown-CimbIo6Y.js";import"./vendor-i18n-DCFGyhQR.js";const ke=({onComplete:y})=>{const[a,q]=r.useState(0),[m,N]=r.useState(""),[d,v]=r.useState(""),[o,x]=r.useState(!1),[w,l]=r.useState(""),[G,C]=r.useState(!1),[M,T]=r.useState("right"),[i,g]=r.useState(null),[B]=r.useState({name:"default",fullPath:ae?"/workspace":""}),[k,p]=r.useState({authenticated:!1,email:null,loading:!0,error:null}),[S,b]=r.useState({authenticated:!1,email:null,loading:!0,error:null}),[A,j]=r.useState({authenticated:!1,email:null,loading:!0,error:null}),{user:h}=re(),L=r.useRef(void 0);r.useEffect(()=>{D()},[]);const D=async()=>{try{const t=await c("/api/user/git-config");if(t.ok){const s=await t.json();s.gitName&&N(s.gitName),s.gitEmail&&v(s.gitEmail)}}catch{}};r.useEffect(()=>{const t=L.current;L.current=i,(t===void 0||t!==null&&i===null)&&(F(),E(),I())},[i]);const F=async()=>{try{const t=await c("/api/cli/claude/status");if(t.ok){const s=await t.json();p({authenticated:s.authenticated,email:s.email,loading:!1,error:s.error||null})}else p({authenticated:!1,email:null,loading:!1,error:"Failed to check status"})}catch(t){p({authenticated:!1,email:null,loading:!1,error:t.message})}},E=async()=>{try{const t=await c("/api/cli/cursor/status");if(t.ok){const s=await t.json();b({authenticated:s.authenticated,email:s.email,loading:!1,error:s.error||null})}else b({authenticated:!1,email:null,loading:!1,error:"Failed to check status"})}catch(t){b({authenticated:!1,email:null,loading:!1,error:t.message})}},I=async()=>{try{const t=await c("/api/cli/codex/status");if(t.ok){const s=await t.json();j({authenticated:s.authenticated,email:s.email,loading:!1,error:s.error||null})}else j({authenticated:!1,email:null,loading:!1,error:"Failed to check status"})}catch(t){j({authenticated:!1,email:null,loading:!1,error:t.message})}},U=()=>g("claude"),Y=()=>g("cursor"),_=()=>g("codex"),z=t=>{t===0&&(i==="claude"?F():i==="cursor"?E():i==="codex"&&I())},u=(t,s="right")=>{T(s),C(!0),setTimeout(()=>{q(t),C(!1)},200)},J=async()=>{if(l(""),a===0){u(1,"right");return}if(a===1){if(!m.trim()||!d.trim()){l("Both git name and email are required");return}if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(d)){l("Please enter a valid email address");return}x(!0);try{const s=await c("/api/user/git-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({gitName:m,gitEmail:d})});if(!s.ok){const n=await s.json();throw new Error(n.error||"Failed to save git configuration")}u(2,"right")}catch(s){l(s.message)}finally{x(!1)}return}u(a+1,"right")},V=()=>{l(""),u(a-1,"left")},W=async()=>{x(!0),l("");try{const t=await c("/api/user/complete-onboarding",{method:"POST"});if(!t.ok){const s=await t.json();throw new Error(s.error||"Failed to complete onboarding")}y&&y()}catch(t){l(t.message)}finally{x(!1)}},f=[{title:"Welcome",required:!1},{title:"Git Identity",required:!0},{title:"Agents",required:!1}],Z=()=>a===0?!0:a===1?m.trim()&&d.trim()&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(d):!0,P=[k,S,A].filter(t=>t.authenticated).length,Q=[{icon:ne,title:"AI Agents",desc:"Claude, Cursor & Codex — unified in one interface",gradient:"from-blue-500/10 to-blue-600/5",iconColor:"text-blue-500"},{icon:oe,title:"Canvas",desc:"Visual workspace with code blocks, diagrams & notes",gradient:"from-violet-500/10 to-violet-600/5",iconColor:"text-violet-500"},{icon:le,title:"Relay",desc:"Bridge your local machine to the web UI seamlessly",gradient:"from-amber-500/10 to-amber-600/5",iconColor:"text-amber-500"}],H=[{name:"Claude Code",status:k,onLogin:U,logo:e.jsx(ee,{size:22}),accent:"blue"},{name:"Cursor",status:S,onLogin:Y,logo:e.jsx(te,{size:22}),accent:"violet"},{name:"OpenAI Codex",status:A,onLogin:_,logo:e.jsx(se,{className:"w-5 h-5"}),accent:"neutral"}],K=G?`opacity-0 ${M==="right"?"translate-x-4":"-translate-x-4"}`:"opacity-100 translate-x-0";return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"min-h-screen bg-background flex items-center justify-center p-4 sm:p-8",children:e.jsxs("div",{className:"w-full max-w-xl",children:[e.jsxs("div",{className:"mb-10",children:[e.jsx("div",{className:"flex items-center justify-between mb-3 px-1",children:f.map((t,s)=>e.jsxs("button",{onClick:()=>{s<a&&u(s,"left")},disabled:s>a,className:`text-xs font-medium tracking-wide uppercase transition-colors duration-300 ${s===a?"text-foreground":s<a?"text-primary cursor-pointer hover:text-primary/80":"text-muted-foreground/50"}`,children:[t.title,t.required&&s===a&&e.jsx("span",{className:"text-destructive ml-1",children:"*"})]},s))}),e.jsx("div",{className:"h-1 bg-muted/60 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full bg-primary rounded-full transition-all duration-500 ease-out",style:{width:`${a/(f.length-1)*100}%`}})})]}),e.jsxs("div",{className:"bg-card rounded-2xl border border-border/60 shadow-xl shadow-black/[0.04] dark:shadow-black/[0.2] overflow-hidden",children:[e.jsxs("div",{className:`p-8 sm:p-10 transition-all duration-200 ease-out ${K}`,children:[a===0&&e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"text-center",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/10 text-primary text-xs font-medium mb-6",children:[e.jsx(ie,{className:"w-3.5 h-3.5"}),"Quick setup — under a minute"]}),e.jsxs("h1",{className:"text-3xl sm:text-4xl font-bold text-foreground tracking-tight leading-tight",children:["Welcome to Upfyn",h!=null&&h.first_name?e.jsxs("span",{className:"text-primary",children:[", ",h.first_name]}):null]}),e.jsx("p",{className:"text-muted-foreground mt-3 text-base max-w-md mx-auto leading-relaxed",children:"Your visual AI coding interface. Connect your favorite agents, manage projects, and build faster."})]}),e.jsx("div",{className:"grid gap-3",children:Q.map((t,s)=>e.jsxs("div",{className:`group flex items-start gap-4 p-4 rounded-xl bg-gradient-to-r ${t.gradient} border border-border/40 hover:border-border/80 transition-all duration-200`,children:[e.jsx("div",{className:`mt-0.5 p-2 rounded-lg bg-background/80 ${t.iconColor} flex-shrink-0`,children:e.jsx(t.icon,{className:"w-5 h-5"})}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold text-foreground text-sm",children:t.title}),e.jsx("p",{className:"text-muted-foreground text-sm mt-0.5",children:t.desc})]})]},s))})]}),a===1&&e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"w-14 h-14 rounded-2xl bg-primary/10 flex items-center justify-center mx-auto mb-5",children:e.jsx(de,{className:"w-7 h-7 text-primary"})}),e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold text-foreground tracking-tight",children:"Git Identity"}),e.jsx("p",{className:"text-muted-foreground mt-2 text-sm max-w-sm mx-auto",children:"Set your name and email for commit attribution"})]}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"gitName",className:"flex items-center gap-2 text-sm font-medium text-foreground mb-2",children:[e.jsx(ce,{className:"w-3.5 h-3.5 text-muted-foreground"}),"Name"]}),e.jsx("input",{type:"text",id:"gitName",value:m,onChange:t=>N(t.target.value),className:"w-full px-4 py-3 border border-border/60 rounded-xl bg-background text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/40 transition-all duration-200",placeholder:"John Doe",required:!0,disabled:o})]}),e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"gitEmail",className:"flex items-center gap-2 text-sm font-medium text-foreground mb-2",children:[e.jsx(ue,{className:"w-3.5 h-3.5 text-muted-foreground"}),"Email"]}),e.jsx("input",{type:"email",id:"gitEmail",value:d,onChange:t=>v(t.target.value),className:"w-full px-4 py-3 border border-border/60 rounded-xl bg-background text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/40 transition-all duration-200",placeholder:"john@example.com",required:!0,disabled:o})]}),e.jsxs("p",{className:"text-xs text-muted-foreground/70 text-center",children:["Applied as ",e.jsx("code",{className:"px-1 py-0.5 rounded bg-muted/60 text-xs",children:"git config --global"})," on your machine"]})]})]}),a===2&&e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold text-foreground tracking-tight",children:"Connect Your Agents"}),e.jsxs("p",{className:"text-muted-foreground mt-2 text-sm max-w-sm mx-auto",children:["Optional — login to one or more AI assistants.",P>0&&e.jsxs("span",{className:"text-primary font-medium",children:[" ",P," connected"]})]})]}),e.jsx("div",{className:"space-y-3",children:H.map((t,s)=>{const n=t.status.authenticated,R=t.status.loading;return e.jsxs("div",{className:`group flex items-center justify-between p-4 rounded-xl border transition-all duration-200 ${n?"bg-primary/5 border-primary/20":"bg-card border-border/50 hover:border-border"}`,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0 ${n?"bg-primary/10":"bg-muted/60"}`,children:t.logo}),e.jsxs("div",{children:[e.jsxs("div",{className:"font-medium text-sm text-foreground flex items-center gap-2",children:[t.name,n&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md bg-green-500/10 text-green-600 dark:text-green-400 text-[10px] font-semibold uppercase tracking-wider",children:[e.jsx(me,{className:"w-3 h-3"}),"Connected"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:R?"Checking...":n?t.status.email||"Ready to use":"Not connected"})]})]}),!n&&!R&&e.jsx("button",{onClick:t.onLogin,className:"px-4 py-2 text-sm font-medium rounded-lg bg-foreground text-background hover:opacity-90 transition-opacity flex-shrink-0",children:"Connect"})]},s)})}),e.jsx("p",{className:"text-xs text-muted-foreground/60 text-center",children:"You can always add or change these in Settings later."})]})]}),w&&e.jsx("div",{className:"mx-8 sm:mx-10 mb-2 p-3 rounded-xl bg-destructive/10 border border-destructive/20",children:e.jsx("p",{className:"text-sm text-destructive",children:w})}),e.jsxs("div",{className:"flex items-center justify-between px-8 sm:px-10 py-5 border-t border-border/40 bg-muted/20",children:[e.jsxs("button",{onClick:V,disabled:a===0||o,className:"flex items-center gap-1.5 text-sm font-medium text-muted-foreground hover:text-foreground disabled:opacity-0 disabled:pointer-events-none transition-all duration-200",children:[e.jsx(xe,{className:"w-4 h-4"}),"Back"]}),a<f.length-1?e.jsx("button",{onClick:J,disabled:!Z()||o,className:"flex items-center gap-2 px-6 py-2.5 bg-primary text-primary-foreground font-medium text-sm rounded-xl hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-sm",children:o?e.jsxs(e.Fragment,{children:[e.jsx($,{className:"w-4 h-4 animate-spin"}),"Saving..."]}):a===0?e.jsxs(e.Fragment,{children:["Get Started",e.jsx(O,{className:"w-4 h-4"})]}):e.jsxs(e.Fragment,{children:["Continue",e.jsx(ge,{className:"w-4 h-4"})]})}):e.jsx("button",{onClick:W,disabled:o,className:"flex items-center gap-2 px-6 py-2.5 bg-primary text-primary-foreground font-medium text-sm rounded-xl hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-sm",children:o?e.jsxs(e.Fragment,{children:[e.jsx($,{className:"w-4 h-4 animate-spin"}),"Finishing..."]}):e.jsxs(e.Fragment,{children:["Start Building",e.jsx(O,{className:"w-4 h-4"})]})})]})]}),e.jsxs("p",{className:"text-center text-xs text-muted-foreground/50 mt-6",children:["Step ",a+1," of ",f.length]})]})}),i&&e.jsx(X,{isOpen:!!i,onClose:()=>g(null),provider:i,project:B,onComplete:z,isOnboarding:!0})]})};export{ke as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as t,j as e}from"./vendor-react-96lCPsRK.js";import{h as y}from"./index-C5ptjuTl.js";import"./vendor-syntax-DuHI9Ok6.js";import"./vendor-markdown-CimbIo6Y.js";import"./vendor-icons-BaD0x9SL.js";import"./vendor-i18n-DCFGyhQR.js";const q=()=>{const[a,f]=t.useState(""),[d,p]=t.useState(""),[l,x]=t.useState(""),[n,g]=t.useState(""),[u,h]=t.useState(""),[s,i]=t.useState(!1),[c,o]=t.useState(""),{register:j}=y(),N=async r=>{if(r.preventDefault(),o(""),n!==u){o("Passwords do not match");return}if(!a.trim()||a.trim().length<2){o("Name must be at least 2 characters");return}if(!d.trim()||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(d)){o("Please enter a valid email address");return}if(n.length<6){o("Password must be at least 6 characters");return}i(!0);const m=a.trim().split(" "),w=m[0]||a.trim(),v=m.slice(1).join(" ")||"",b=await j(w,v,n,d.trim(),l.trim()||null);b.success||o(b.error),i(!1)};return e.jsx("div",{className:"min-h-screen bg-background flex items-center justify-center p-4",children:e.jsx("div",{className:"w-full max-w-md",children:e.jsxs("div",{className:"bg-card rounded-lg shadow-lg border border-border p-8 space-y-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"flex justify-center mb-4",children:e.jsx("img",{src:"/logo.svg",alt:"Upfyn-Code",className:"w-16 h-16",onError:r=>{r.target.style.display="none"}})}),e.jsx("h1",{className:"text-2xl font-bold text-foreground",children:"Create Your Account"}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"Sign up to start using Upfyn-Code"})]}),e.jsxs("form",{onSubmit:N,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"name",className:"block text-sm font-medium text-foreground mb-1",children:"Full Name"}),e.jsx("input",{type:"text",id:"name",value:a,onChange:r=>f(r.target.value),className:"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:"Your full name",required:!0,disabled:s})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"email",className:"block text-sm font-medium text-foreground mb-1",children:"Email"}),e.jsx("input",{type:"email",id:"email",value:d,onChange:r=>p(r.target.value),className:"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:"you@example.com",required:!0,disabled:s})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"phone",className:"block text-sm font-medium text-foreground mb-1",children:"Mobile Number"}),e.jsx("input",{type:"tel",id:"phone",value:l,onChange:r=>x(r.target.value),className:"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:"+91 9876543210",disabled:s})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"password",className:"block text-sm font-medium text-foreground mb-1",children:"Password"}),e.jsx("input",{type:"password",id:"password",value:n,onChange:r=>g(r.target.value),className:"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:"At least 6 characters",required:!0,disabled:s})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"confirmPassword",className:"block text-sm font-medium text-foreground mb-1",children:"Confirm Password"}),e.jsx("input",{type:"password",id:"confirmPassword",value:u,onChange:r=>h(r.target.value),className:"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:"Confirm your password",required:!0,disabled:s})]}),c&&e.jsx("div",{className:"p-3 bg-red-100 dark:bg-red-900/20 border border-red-300 dark:border-red-800 rounded-md",children:e.jsx("p",{className:"text-sm text-red-700 dark:text-red-400",children:c})}),e.jsx("button",{type:"submit",disabled:s,className:"w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white font-medium py-2 px-4 rounded-md transition-colors duration-200",children:s?"Creating account...":"Create Account"})]})]})})})};export{q as default};
|