@geminilight/mindos 0.6.58 → 0.6.59
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/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +24 -24
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +1 -1
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +2 -2
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +3 -3
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +2 -2
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +3 -3
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +2 -2
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +2 -2
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +2 -2
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +2 -8
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js +2 -2
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +24 -24
- package/_standalone/.next/server/chunks/3484.js +1 -1
- package/_standalone/.next/server/chunks/530.js +65 -66
- package/_standalone/.next/server/chunks/{6793.js → 8343.js} +2 -2
- package/_standalone/.next/server/chunks/9787.js +2 -0
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/{1814.a7c127b2c73d1f70.js → 1814.a79b84d37df75c43.js} +1 -1
- package/_standalone/.next/static/chunks/3427-2e61a5df1f5e55fb.js +1 -0
- package/_standalone/.next/static/chunks/{1053-fe009233cff06e72.js → 5581-dac72e9f16e5ea29.js} +3 -3
- package/_standalone/.next/static/chunks/6297-085daa21037d5f81.js +1 -0
- package/_standalone/.next/static/chunks/{7249-fa98ca10e9a10f39.js → 7249-6cf8f2b78718c59e.js} +1 -1
- package/_standalone/.next/static/chunks/8520-56ec9ff087c15204.js +22 -0
- package/_standalone/.next/static/chunks/9905-a19d379cb225246e.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/{page-7bdeab5af8e4f5f2.js → page-35ea6de1af2be3b5.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/page-b172ea3743adb047.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/{page-5a72144d1080a699.js → page-6d2f49651c0061f7.js} +1 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-84b95256f6e38aae.js +11 -0
- package/_standalone/.next/static/chunks/app/explore/{page-d3d99308146c2240.js → page-d9f58000bc445360.js} +2 -2
- package/_standalone/.next/static/chunks/app/help/{page-222df603080b5fab.js → page-f8cb806371b3175f.js} +1 -1
- package/_standalone/.next/static/chunks/app/inbox/history/{page-07819cf95cb0805f.js → page-26e71fb6f716a4c4.js} +1 -1
- package/_standalone/.next/static/chunks/app/layout-b89b0d955f39a753.js +164 -0
- package/_standalone/.next/static/chunks/app/login/{page-0eeef685052869a6.js → page-18fb00d568cd1f0e.js} +1 -1
- package/_standalone/.next/static/chunks/app/page-a8e6f085f38388bf.js +1 -0
- package/_standalone/.next/static/chunks/app/setup/{page-99fcfc460fa29733.js → page-821714e7477be46c.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/{page-54cbd5c98d9de69b.js → page-f92b728b78ac0f7e.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/{not-found-fc04c2bd4f35bc6f.js → not-found-6e0c75ad26ce8572.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-f87f4901b5e1a88f.js +12 -0
- package/_standalone/.next/static/chunks/app/wiki/page-641edb1f3cff2f93.js +1 -0
- package/_standalone/.next/static/chunks/{webpack-2c19436659aa657b.js → webpack-72e8d9e9073fd1f9.js} +1 -1
- package/_standalone/.next/static/css/6c104b118d3bc9b7.css +1 -0
- package/_standalone/.next/trace +64 -64
- package/_standalone/app/globals.css +2 -1
- package/_standalone/components/AskFab.tsx +4 -4
- package/_standalone/components/AskModal.tsx +1 -1
- package/_standalone/components/GuideCard.tsx +101 -152
- package/_standalone/components/RightAskPanel.tsx +2 -2
- package/_standalone/components/ask/AskContent.tsx +90 -51
- package/_standalone/components/ask/AskHeader.tsx +218 -18
- package/_standalone/components/ask/MessageList.tsx +66 -47
- package/_standalone/components/ask/SessionHistory.tsx +86 -60
- package/_standalone/components/ask/SessionTabBar.tsx +29 -21
- package/_standalone/components/ask/ThinkingBlock.tsx +6 -5
- package/_standalone/components/ask/ToolCallBlock.tsx +10 -9
- package/_standalone/components/settings/SettingsContent.tsx +1 -1
- package/_standalone/data/skills/mindos/SKILL.md +67 -15
- package/_standalone/data/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/hooks/useAskSession.ts +23 -1
- package/_standalone/lib/stores/locale-store.ts +20 -6
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/globals.css +2 -1
- package/app/app/layout.tsx +16 -4
- package/app/components/AskFab.tsx +4 -4
- package/app/components/AskModal.tsx +1 -1
- package/app/components/GuideCard.tsx +101 -152
- package/app/components/HomeContent.tsx +116 -575
- package/app/components/RightAskPanel.tsx +2 -2
- package/app/components/WikiHomeContent.tsx +151 -3
- package/app/components/ask/AskContent.tsx +90 -51
- package/app/components/ask/AskHeader.tsx +218 -18
- package/app/components/ask/MessageList.tsx +66 -47
- package/app/components/ask/SessionHistory.tsx +86 -60
- package/app/components/ask/SessionTabBar.tsx +29 -21
- package/app/components/ask/ThinkingBlock.tsx +6 -5
- package/app/components/ask/ToolCallBlock.tsx +10 -9
- package/app/components/settings/SettingsContent.tsx +1 -1
- package/app/data/skills/mindos/SKILL.md +67 -15
- package/app/data/skills/mindos-zh/SKILL.md +67 -11
- package/app/hooks/useAskSession.ts +23 -1
- package/app/lib/i18n/modules/ai-chat.ts +97 -10
- package/app/lib/i18n/modules/onboarding.ts +12 -12
- package/app/lib/stores/LocaleStoreInit.tsx +24 -1
- package/app/lib/stores/locale-store.ts +20 -6
- package/app/lib/types.ts +1 -0
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +67 -15
- package/skills/mindos/references/knowledge-health.md +120 -0
- package/skills/mindos-max/SKILL.md +52 -5
- package/skills/mindos-max-zh/SKILL.md +55 -6
- package/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/.next/server/chunks/2364.js +0 -2
- package/_standalone/.next/server/chunks/357.js +0 -1
- package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +0 -1
- package/_standalone/.next/static/chunks/2218-d54538000574ffef.js +0 -1
- package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +0 -1
- package/_standalone/.next/static/chunks/9274-296ab35f9f09e42e.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-b0103509ce34444b.js +0 -11
- package/_standalone/.next/static/chunks/app/layout-7e02ddf4144b01f1.js +0 -186
- package/_standalone/.next/static/chunks/app/page-6a6a12bd6d6812d0.js +0 -7
- package/_standalone/.next/static/chunks/app/view/[...path]/page-ca7bdcbf27f88a46.js +0 -12
- package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +0 -1
- package/_standalone/.next/static/css/fd84c8316ead16eb.css +0 -1
- /package/_standalone/.next/static/{2ksXveDzEcnCMRIElDkLq → u8p6oIRTcr_ns-ElNZ9rl}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{2ksXveDzEcnCMRIElDkLq → u8p6oIRTcr_ns-ElNZ9rl}/_ssgManifest.js +0 -0
package/app/app/globals.css
CHANGED
|
@@ -180,7 +180,7 @@ body {
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
.prose {
|
|
183
|
-
font-family: var(--prose-font-override, '
|
|
183
|
+
font-family: var(--prose-font-override, 'IBM Plex Sans', system-ui, sans-serif);
|
|
184
184
|
color: var(--prose-body);
|
|
185
185
|
line-height: 1.85;
|
|
186
186
|
font-size: var(--prose-font-size-override, 0.95rem);
|
|
@@ -238,6 +238,7 @@ body {
|
|
|
238
238
|
|
|
239
239
|
/* Ask Panel — compact prose for side panel chat bubbles */
|
|
240
240
|
.prose.prose-panel {
|
|
241
|
+
font-family: 'IBM Plex Sans', system-ui, sans-serif;
|
|
241
242
|
font-size: 0.8125rem !important;
|
|
242
243
|
line-height: 1.6;
|
|
243
244
|
}
|
package/app/app/layout.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import ErrorBoundary from '@/components/ErrorBoundary';
|
|
|
9
9
|
import Toaster from '@/components/ui/Toaster';
|
|
10
10
|
import RegisterSW from './register-sw';
|
|
11
11
|
import UpdateOverlay from '@/components/UpdateOverlay';
|
|
12
|
-
import { cookies } from 'next/headers';
|
|
12
|
+
import { cookies, headers } from 'next/headers';
|
|
13
13
|
import type { Locale } from '@/lib/i18n';
|
|
14
14
|
import '@/lib/renderers/index'; // globally register built-in renderers once
|
|
15
15
|
|
|
@@ -67,9 +67,21 @@ export default async function RootLayout({
|
|
|
67
67
|
console.error('[RootLayout] Failed to load file tree:', err);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
// Read locale from cookie
|
|
70
|
+
// Read locale from cookie, or infer from Accept-Language header
|
|
71
|
+
// This matches the client pre-hydration script logic:
|
|
72
|
+
// localStorage > system language preference (via Accept-Language)
|
|
71
73
|
const cookieStore = await cookies();
|
|
72
|
-
const
|
|
74
|
+
const cookieLocale = cookieStore.get('locale')?.value;
|
|
75
|
+
let ssrLocale: Locale = 'en';
|
|
76
|
+
if (cookieLocale === 'zh') {
|
|
77
|
+
ssrLocale = 'zh';
|
|
78
|
+
} else if (cookieLocale !== 'en') {
|
|
79
|
+
// Cookie not set or invalid — infer from Accept-Language header
|
|
80
|
+
// (matches client: navigator.language.startsWith('zh') ? 'zh' : 'en')
|
|
81
|
+
const headerStore = await headers();
|
|
82
|
+
const acceptLanguage = headerStore.get('Accept-Language') || '';
|
|
83
|
+
ssrLocale = acceptLanguage.includes('zh') ? 'zh' : 'en';
|
|
84
|
+
}
|
|
73
85
|
|
|
74
86
|
return (
|
|
75
87
|
<html lang={ssrLocale} suppressHydrationWarning>
|
|
@@ -92,7 +104,7 @@ export default async function RootLayout({
|
|
|
92
104
|
{/* Apply user appearance settings before first paint, preventing flash */}
|
|
93
105
|
<script
|
|
94
106
|
dangerouslySetInnerHTML={{
|
|
95
|
-
__html: `(function(){try{var s=localStorage.getItem('theme');var dark=s&&s!=='system'?s==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',dark);var cw=localStorage.getItem('content-width');if(cw)document.documentElement.style.setProperty('--content-width-override',cw);var pf=localStorage.getItem('prose-font');if(pf==='geist'){pf='inter';localStorage.setItem('prose-font','inter')}var fm={lora:'"Lora", Georgia, serif','ibm-plex-sans':'"IBM Plex Sans", sans-serif',inter:'var(--font-inter), sans-serif','ibm-plex-mono':'"IBM Plex Mono", monospace'};if(pf&&fm[pf])document.documentElement.style.setProperty('--prose-font-override',fm[pf]);var loc=localStorage.getItem('locale')||'system';var rl=loc==='system'?(navigator.language.startsWith('zh')?'zh':'en'):loc;document.documentElement.lang=rl==='zh'?'zh':'en';document.cookie='locale='+rl+';path=/;max-age=31536000;SameSite=Lax'}catch(e){}})();`,
|
|
107
|
+
__html: `(function(){try{var s=localStorage.getItem('theme');var dark=s&&s!=='system'?s==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',dark);var cw=localStorage.getItem('content-width');if(cw)document.documentElement.style.setProperty('--content-width-override',cw);var pf=localStorage.getItem('prose-font');if(pf==='geist'){pf='inter';localStorage.setItem('prose-font','inter')}var fm={lora:'"Lora", Georgia, serif','ibm-plex-sans':'"IBM Plex Sans", sans-serif',inter:'var(--font-inter), sans-serif','ibm-plex-mono':'"IBM Plex Mono", monospace'};if(pf&&fm[pf])document.documentElement.style.setProperty('--prose-font-override',fm[pf]);var loc=localStorage.getItem('locale')||'system';var rl=loc==='system'?(navigator.language.startsWith('zh')?'zh':'en'):loc;window.__mindos_locale__=rl;document.documentElement.lang=rl==='zh'?'zh':'en';document.cookie='locale='+rl+';path=/;max-age=31536000;SameSite=Lax'}catch(e){}})();`,
|
|
96
108
|
}}
|
|
97
109
|
/>
|
|
98
110
|
</head>
|
|
@@ -22,11 +22,11 @@ export default function AskFab({ onToggle, askPanelOpen }: AskFabProps) {
|
|
|
22
22
|
fixed z-40 bottom-5 right-5
|
|
23
23
|
items-center justify-center
|
|
24
24
|
gap-0 hover:gap-2
|
|
25
|
-
p-3 rounded-
|
|
26
|
-
text-
|
|
27
|
-
shadow-
|
|
25
|
+
p-3 rounded-2xl
|
|
26
|
+
text-[var(--amber-foreground)] font-medium text-[13px]
|
|
27
|
+
shadow-md shadow-[var(--amber)]/15
|
|
28
28
|
transition-all duration-200 ease-out
|
|
29
|
-
hover:shadow-
|
|
29
|
+
hover:shadow-lg hover:shadow-[var(--amber)]/20
|
|
30
30
|
active:scale-95 cursor-pointer overflow-hidden
|
|
31
31
|
${askPanelOpen ? 'opacity-0 pointer-events-none translate-y-2' : 'opacity-100 translate-y-0'}
|
|
32
32
|
`}
|
|
@@ -29,7 +29,7 @@ export default function AskModal({ open, onClose, currentFile, initialMessage, i
|
|
|
29
29
|
role="dialog"
|
|
30
30
|
aria-modal="true"
|
|
31
31
|
aria-label={t.ask.title}
|
|
32
|
-
className="w-full md:max-w-2xl md:mx-4 bg-card border-t md:border border-border rounded-t-2xl md:rounded-
|
|
32
|
+
className="w-full md:max-w-2xl md:mx-4 bg-card border-t md:border border-border/60 rounded-t-2xl md:rounded-2xl shadow-2xl flex flex-col h-[92vh] md:h-auto md:max-h-[75vh]"
|
|
33
33
|
>
|
|
34
34
|
<AskContent
|
|
35
35
|
visible={open}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
|
-
import { X, Sparkles, Upload, MessageCircle, ExternalLink, Check,
|
|
4
|
+
import { X, Sparkles, Upload, MessageCircle, ExternalLink, Check, Copy, ChevronDown } from 'lucide-react';
|
|
5
5
|
import { copyToClipboard } from '@/lib/clipboard';
|
|
6
6
|
import { toast } from '@/lib/toast';
|
|
7
7
|
import Link from 'next/link';
|
|
@@ -9,6 +9,7 @@ import { useLocale } from '@/lib/stores/locale-store';
|
|
|
9
9
|
import { openAskModal } from '@/hooks/useAskModal';
|
|
10
10
|
import { walkthroughSteps } from './walkthrough/steps';
|
|
11
11
|
import type { GuideState } from '@/lib/settings';
|
|
12
|
+
|
|
12
13
|
export default function GuideCard() {
|
|
13
14
|
const { t } = useLocale();
|
|
14
15
|
const g = t.guide;
|
|
@@ -18,7 +19,6 @@ export default function GuideCard() {
|
|
|
18
19
|
const [isFirstVisit, setIsFirstVisit] = useState(false);
|
|
19
20
|
const [step3Done, setStep3Done] = useState(false);
|
|
20
21
|
|
|
21
|
-
// Fetch guide state from backend
|
|
22
22
|
const fetchGuideState = useCallback(() => {
|
|
23
23
|
fetch('/api/setup')
|
|
24
24
|
.then(r => r.json())
|
|
@@ -37,10 +37,8 @@ export default function GuideCard() {
|
|
|
37
37
|
|
|
38
38
|
useEffect(() => {
|
|
39
39
|
fetchGuideState();
|
|
40
|
-
|
|
41
40
|
const handleFirstVisit = () => { setIsFirstVisit(true); };
|
|
42
41
|
window.addEventListener('mindos:first-visit', handleFirstVisit);
|
|
43
|
-
|
|
44
42
|
const handleGuideUpdate = () => fetchGuideState();
|
|
45
43
|
window.addEventListener('focus', handleGuideUpdate);
|
|
46
44
|
window.addEventListener('guide-state-updated', handleGuideUpdate);
|
|
@@ -68,7 +66,6 @@ export default function GuideCard() {
|
|
|
68
66
|
}, [patchGuide]);
|
|
69
67
|
|
|
70
68
|
// ── Step 1: Import ──
|
|
71
|
-
|
|
72
69
|
const handleImportClick = useCallback(() => {
|
|
73
70
|
window.dispatchEvent(new CustomEvent('mindos:open-import'));
|
|
74
71
|
}, []);
|
|
@@ -78,7 +75,6 @@ export default function GuideCard() {
|
|
|
78
75
|
setExpanded(null);
|
|
79
76
|
}, [patchGuide]);
|
|
80
77
|
|
|
81
|
-
// Auto-mark step 1 done when files change (import completes, space created, etc.)
|
|
82
78
|
useEffect(() => {
|
|
83
79
|
if (!guideState || guideState.step1Done) return;
|
|
84
80
|
const handler = () => patchGuide({ step1Done: true });
|
|
@@ -87,7 +83,6 @@ export default function GuideCard() {
|
|
|
87
83
|
}, [guideState, guideState?.step1Done, patchGuide]);
|
|
88
84
|
|
|
89
85
|
// ── Step 2: AI verify ──
|
|
90
|
-
|
|
91
86
|
const handleStartAI = useCallback(() => {
|
|
92
87
|
const gs = guideState;
|
|
93
88
|
const isEmpty = gs?.template === 'empty';
|
|
@@ -96,7 +91,6 @@ export default function GuideCard() {
|
|
|
96
91
|
}, [guideState, g]);
|
|
97
92
|
|
|
98
93
|
// ── Step 3: Cross-agent copy ──
|
|
99
|
-
|
|
100
94
|
const handleCopyPrompt = useCallback(async () => {
|
|
101
95
|
const ok = await copyToClipboard(g.agent.copyPrompt);
|
|
102
96
|
if (ok) toast.copy();
|
|
@@ -109,7 +103,6 @@ export default function GuideCard() {
|
|
|
109
103
|
}, [patchGuide]);
|
|
110
104
|
|
|
111
105
|
// ── Next-step prompts ──
|
|
112
|
-
|
|
113
106
|
const handleNextStepClick = useCallback(() => {
|
|
114
107
|
if (!guideState) return;
|
|
115
108
|
const idx = guideState.nextStepIndex;
|
|
@@ -121,15 +114,12 @@ export default function GuideCard() {
|
|
|
121
114
|
}, [guideState, g, patchGuide]);
|
|
122
115
|
|
|
123
116
|
// ── Auto-expand on step transitions ──
|
|
124
|
-
|
|
125
|
-
// First visit: expand step 1
|
|
126
117
|
useEffect(() => {
|
|
127
118
|
if (isFirstVisit && guideState && !guideState.step1Done) {
|
|
128
119
|
setExpanded('import');
|
|
129
120
|
}
|
|
130
121
|
}, [isFirstVisit, guideState]);
|
|
131
122
|
|
|
132
|
-
// Step transition: auto-expand next step
|
|
133
123
|
const prevStepRef = useRef({ s1: false, s2: false });
|
|
134
124
|
useEffect(() => {
|
|
135
125
|
if (!guideState) return;
|
|
@@ -145,7 +135,6 @@ export default function GuideCard() {
|
|
|
145
135
|
}, [guideState?.step1Done, guideState?.askedAI, guideState]);
|
|
146
136
|
|
|
147
137
|
// ── Auto-dismiss final state ──
|
|
148
|
-
|
|
149
138
|
const step1Done = guideState?.step1Done ?? false;
|
|
150
139
|
const step2Done = guideState?.askedAI ?? false;
|
|
151
140
|
const nextIdx = guideState?.nextStepIndex ?? 0;
|
|
@@ -161,7 +150,6 @@ export default function GuideCard() {
|
|
|
161
150
|
}, [allNextDone, handleDismiss]);
|
|
162
151
|
|
|
163
152
|
// ── Render guards ──
|
|
164
|
-
|
|
165
153
|
if (!guideState) return null;
|
|
166
154
|
|
|
167
155
|
const walkthroughActive = guideState.walkthroughStep !== undefined
|
|
@@ -170,17 +158,14 @@ export default function GuideCard() {
|
|
|
170
158
|
&& !guideState.walkthroughDismissed;
|
|
171
159
|
if (walkthroughActive) return null;
|
|
172
160
|
|
|
173
|
-
// If both steps 1+2 were already done on load (e.g. page refresh), step3Done is local
|
|
174
|
-
// and starts false — this lets the user see step 3 again, which is useful.
|
|
175
161
|
const showStep3 = step1Done && step2Done && !step3Done;
|
|
176
162
|
|
|
177
163
|
// ── Final state: all next-steps done ──
|
|
178
|
-
|
|
179
164
|
if (allCoreDone && allNextDone) {
|
|
180
165
|
return (
|
|
181
|
-
<div className="
|
|
182
|
-
<Sparkles size={
|
|
183
|
-
<span className="text-
|
|
166
|
+
<div className="rounded-lg border border-border/50 px-4 py-3 flex items-center gap-3 animate-in fade-in duration-300">
|
|
167
|
+
<Sparkles size={14} className="text-[var(--amber)] shrink-0" />
|
|
168
|
+
<span className="text-xs font-medium flex-1 text-foreground">
|
|
184
169
|
{g.done.titleFinal}
|
|
185
170
|
</span>
|
|
186
171
|
<Link
|
|
@@ -190,159 +175,159 @@ export default function GuideCard() {
|
|
|
190
175
|
{t.walkthrough.exploreCta}
|
|
191
176
|
</Link>
|
|
192
177
|
<button onClick={handleDismiss} className="p-1 rounded hover:bg-muted transition-colors text-muted-foreground">
|
|
193
|
-
<X size={
|
|
178
|
+
<X size={12} />
|
|
194
179
|
</button>
|
|
195
180
|
</div>
|
|
196
181
|
);
|
|
197
182
|
}
|
|
198
183
|
|
|
199
184
|
// ── Done state: next-step prompts ──
|
|
200
|
-
|
|
201
185
|
if (allCoreDone) {
|
|
202
186
|
const step = g.done.steps[nextIdx];
|
|
203
187
|
return (
|
|
204
|
-
<div className="
|
|
188
|
+
<div className="rounded-lg border border-border/50 px-4 py-3 animate-in fade-in duration-300">
|
|
205
189
|
<div className="flex items-center gap-3">
|
|
206
|
-
<Sparkles size={
|
|
207
|
-
<span className="text-
|
|
190
|
+
<Sparkles size={14} className="text-[var(--amber)] shrink-0" />
|
|
191
|
+
<span className="text-xs font-medium flex-1 text-foreground">
|
|
208
192
|
{g.done.title}
|
|
209
193
|
</span>
|
|
210
194
|
<button onClick={handleDismiss} className="p-1 rounded hover:bg-muted transition-colors text-muted-foreground">
|
|
211
|
-
<X size={
|
|
195
|
+
<X size={12} />
|
|
212
196
|
</button>
|
|
213
197
|
</div>
|
|
214
198
|
{step && (
|
|
215
199
|
<button
|
|
216
200
|
onClick={handleNextStepClick}
|
|
217
|
-
className="mt-
|
|
201
|
+
className="mt-2 ml-6 flex items-center gap-1.5 text-xs text-[var(--amber)] transition-colors hover:opacity-80 cursor-pointer"
|
|
218
202
|
>
|
|
219
|
-
<ChevronRight size={14} />
|
|
220
203
|
<span>{step.hint}</span>
|
|
204
|
+
<ChevronDown size={10} className="-rotate-90" />
|
|
221
205
|
</button>
|
|
222
206
|
)}
|
|
223
207
|
</div>
|
|
224
208
|
);
|
|
225
209
|
}
|
|
226
210
|
|
|
227
|
-
// ──
|
|
211
|
+
// ── Steps data ──
|
|
212
|
+
const steps = [
|
|
213
|
+
{ key: 'import' as const, done: step1Done, icon: Upload, title: g.import.title, dimmed: false },
|
|
214
|
+
{ key: 'ai' as const, done: step2Done, icon: MessageCircle, title: g.ai.title, dimmed: !step1Done },
|
|
215
|
+
{ key: 'agent' as const, done: step3Done, icon: ExternalLink, title: g.agent.title, dimmed: !step1Done || !step2Done },
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
const handleStepClick = (key: 'import' | 'ai' | 'agent', done: boolean, dimmed: boolean) => {
|
|
219
|
+
if (done || dimmed) return;
|
|
220
|
+
setExpanded(expanded === key ? null : key);
|
|
221
|
+
};
|
|
228
222
|
|
|
223
|
+
// ── Main guide card ──
|
|
229
224
|
return (
|
|
230
|
-
<div className="
|
|
225
|
+
<div className="rounded-lg border border-border/50 overflow-hidden">
|
|
226
|
+
|
|
227
|
+
{/* Header row with inline steps */}
|
|
228
|
+
<div className="flex items-center gap-2 px-4 py-3">
|
|
229
|
+
<Sparkles size={14} className="text-[var(--amber)] shrink-0" />
|
|
230
|
+
<span className="text-xs font-semibold text-foreground mr-2">{g.title}</span>
|
|
231
|
+
|
|
232
|
+
{/* Step indicators — horizontal */}
|
|
233
|
+
<div className="flex items-center gap-1 flex-1 min-w-0">
|
|
234
|
+
{steps.map((s, i) => {
|
|
235
|
+
const Icon = s.icon;
|
|
236
|
+
const isActive = expanded === s.key;
|
|
237
|
+
const isClickable = !s.done && !s.dimmed;
|
|
238
|
+
return (
|
|
239
|
+
<button
|
|
240
|
+
key={s.key}
|
|
241
|
+
type="button"
|
|
242
|
+
onClick={() => handleStepClick(s.key, s.done, s.dimmed)}
|
|
243
|
+
disabled={s.done || s.dimmed}
|
|
244
|
+
className={`flex items-center gap-1.5 px-2.5 py-1 rounded-md text-2xs font-medium transition-all ${
|
|
245
|
+
s.done
|
|
246
|
+
? 'text-success/70'
|
|
247
|
+
: s.dimmed
|
|
248
|
+
? 'text-muted-foreground/30'
|
|
249
|
+
: isActive
|
|
250
|
+
? 'bg-[var(--amber)]/10 text-[var(--amber)]'
|
|
251
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
|
|
252
|
+
} ${isClickable ? 'cursor-pointer' : ''}`}
|
|
253
|
+
>
|
|
254
|
+
{s.done ? (
|
|
255
|
+
<Check size={11} className="shrink-0" />
|
|
256
|
+
) : (
|
|
257
|
+
<span className={`flex items-center justify-center w-4 h-4 rounded-full text-[9px] font-bold shrink-0 ${
|
|
258
|
+
isActive ? 'bg-[var(--amber)] text-white' : s.dimmed ? 'bg-muted/50 text-muted-foreground/30' : 'bg-muted text-muted-foreground'
|
|
259
|
+
}`}>
|
|
260
|
+
{i + 1}
|
|
261
|
+
</span>
|
|
262
|
+
)}
|
|
263
|
+
<span className="truncate hidden sm:inline">{s.title}</span>
|
|
264
|
+
</button>
|
|
265
|
+
);
|
|
266
|
+
})}
|
|
267
|
+
</div>
|
|
231
268
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
<Sparkles size={16} className="text-[var(--amber)]" />
|
|
235
|
-
<span className="text-sm font-semibold flex-1 text-foreground">
|
|
236
|
-
{g.title}
|
|
237
|
-
</span>
|
|
238
|
-
<button onClick={handleDismiss} className="p-1 rounded hover:bg-muted transition-colors text-muted-foreground">
|
|
239
|
-
<X size={14} />
|
|
269
|
+
<button onClick={handleDismiss} className="p-1 rounded hover:bg-muted transition-colors text-muted-foreground shrink-0">
|
|
270
|
+
<X size={12} />
|
|
240
271
|
</button>
|
|
241
272
|
</div>
|
|
242
273
|
|
|
243
|
-
{/*
|
|
244
|
-
<div className="grid grid-cols-1 sm:grid-cols-3 gap-2 px-5 py-3">
|
|
245
|
-
<TaskCard
|
|
246
|
-
icon={<Upload size={16} />}
|
|
247
|
-
title={g.import.title}
|
|
248
|
-
cta={g.import.cta}
|
|
249
|
-
done={step1Done}
|
|
250
|
-
active={expanded === 'import'}
|
|
251
|
-
onClick={() => !step1Done ? setExpanded(expanded === 'import' ? null : 'import') : null}
|
|
252
|
-
/>
|
|
253
|
-
<TaskCard
|
|
254
|
-
icon={<MessageCircle size={16} />}
|
|
255
|
-
title={g.ai.title}
|
|
256
|
-
cta={g.ai.cta}
|
|
257
|
-
done={step2Done}
|
|
258
|
-
active={expanded === 'ai'}
|
|
259
|
-
dimmed={!step1Done}
|
|
260
|
-
onClick={() => {
|
|
261
|
-
if (step2Done || !step1Done) return;
|
|
262
|
-
setExpanded(expanded === 'ai' ? null : 'ai');
|
|
263
|
-
}}
|
|
264
|
-
/>
|
|
265
|
-
<TaskCard
|
|
266
|
-
icon={<ExternalLink size={16} />}
|
|
267
|
-
title={g.agent.title}
|
|
268
|
-
cta={g.agent.cta}
|
|
269
|
-
done={step3Done}
|
|
270
|
-
active={expanded === 'agent'}
|
|
271
|
-
dimmed={!step1Done || !step2Done}
|
|
272
|
-
onClick={() => {
|
|
273
|
-
if (!step1Done || !step2Done) return;
|
|
274
|
-
setExpanded(expanded === 'agent' ? null : 'agent');
|
|
275
|
-
}}
|
|
276
|
-
/>
|
|
277
|
-
</div>
|
|
278
|
-
|
|
279
|
-
{/* ── Step 1 expanded: Import files ── */}
|
|
274
|
+
{/* ── Step 1 expanded ── */}
|
|
280
275
|
{expanded === 'import' && !step1Done && (
|
|
281
|
-
<div className="px-
|
|
282
|
-
<div className="
|
|
283
|
-
<p className="text-xs text-muted-foreground
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
className="text-xs px-3 py-1 rounded-lg text-muted-foreground transition-colors hover:bg-muted"
|
|
297
|
-
>
|
|
298
|
-
{g.skip}
|
|
299
|
-
</button>
|
|
300
|
-
</div>
|
|
276
|
+
<div className="px-4 pb-3 animate-in fade-in slide-in-from-top-1 duration-150">
|
|
277
|
+
<div className="flex items-center gap-3 pl-6">
|
|
278
|
+
<p className="text-xs text-muted-foreground flex-1">{g.import.desc}</p>
|
|
279
|
+
<button
|
|
280
|
+
onClick={handleImportClick}
|
|
281
|
+
className="shrink-0 text-xs font-medium px-3 py-1.5 rounded-md bg-[var(--amber)] text-[var(--amber-foreground)] transition-all hover:opacity-90"
|
|
282
|
+
>
|
|
283
|
+
{g.import.button}
|
|
284
|
+
</button>
|
|
285
|
+
<button
|
|
286
|
+
onClick={handleSkipImport}
|
|
287
|
+
className="shrink-0 text-xs px-2 py-1 rounded-md text-muted-foreground/60 hover:text-muted-foreground hover:bg-muted transition-colors"
|
|
288
|
+
>
|
|
289
|
+
{g.skip}
|
|
290
|
+
</button>
|
|
301
291
|
</div>
|
|
302
292
|
</div>
|
|
303
293
|
)}
|
|
304
294
|
|
|
305
|
-
{/* ── Step 2 expanded
|
|
295
|
+
{/* ── Step 2 expanded ── */}
|
|
306
296
|
{expanded === 'ai' && step1Done && !step2Done && (
|
|
307
|
-
<div className="px-
|
|
308
|
-
<div className="
|
|
309
|
-
<p className="text-xs text-muted-foreground
|
|
310
|
-
{g.ai.desc}
|
|
311
|
-
</p>
|
|
297
|
+
<div className="px-4 pb-3 animate-in fade-in slide-in-from-top-1 duration-150">
|
|
298
|
+
<div className="flex items-center gap-3 pl-6">
|
|
299
|
+
<p className="text-xs text-muted-foreground flex-1">{g.ai.desc}</p>
|
|
312
300
|
<button
|
|
313
301
|
onClick={handleStartAI}
|
|
314
|
-
className="text-xs font-medium px-
|
|
315
|
-
style={{ background: 'var(--amber)', color: 'var(--amber-foreground)' }}
|
|
302
|
+
className="shrink-0 text-xs font-medium px-3 py-1.5 rounded-md bg-[var(--amber)] text-[var(--amber-foreground)] transition-all hover:opacity-90"
|
|
316
303
|
>
|
|
317
|
-
{g.ai.cta}
|
|
304
|
+
{g.ai.cta}
|
|
318
305
|
</button>
|
|
319
306
|
</div>
|
|
320
307
|
</div>
|
|
321
308
|
)}
|
|
322
309
|
|
|
323
|
-
{/* ── Step 3 expanded
|
|
310
|
+
{/* ── Step 3 expanded ── */}
|
|
324
311
|
{expanded === 'agent' && showStep3 && (
|
|
325
|
-
<div className="px-
|
|
326
|
-
<div className="
|
|
327
|
-
<p className="text-xs text-muted-foreground mb-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<div className="relative rounded-lg border border-border bg-muted/50 p-3 pr-16">
|
|
331
|
-
<p className="text-xs font-mono text-foreground leading-relaxed whitespace-pre-wrap">
|
|
312
|
+
<div className="px-4 pb-3 animate-in fade-in slide-in-from-top-1 duration-150">
|
|
313
|
+
<div className="pl-6">
|
|
314
|
+
<p className="text-xs text-muted-foreground mb-2">{g.agent.desc}</p>
|
|
315
|
+
<div className="relative rounded-md bg-muted/50 p-3 pr-20">
|
|
316
|
+
<p className="text-xs font-mono text-foreground/80 leading-relaxed whitespace-pre-wrap">
|
|
332
317
|
{g.agent.copyPrompt}
|
|
333
318
|
</p>
|
|
334
319
|
<button
|
|
335
320
|
onClick={handleCopyPrompt}
|
|
336
|
-
className="absolute top-2 right-2 flex items-center gap-1 text-2xs font-medium px-2
|
|
321
|
+
className="absolute top-2 right-2 flex items-center gap-1 text-2xs font-medium px-2 py-1 rounded-md bg-background border border-border/50 text-muted-foreground hover:text-foreground transition-colors"
|
|
337
322
|
>
|
|
338
|
-
<Copy size={
|
|
323
|
+
<Copy size={10} />
|
|
339
324
|
{g.agent.copy}
|
|
340
325
|
</button>
|
|
341
326
|
</div>
|
|
342
|
-
<div className="flex
|
|
327
|
+
<div className="flex justify-end mt-2">
|
|
343
328
|
<button
|
|
344
329
|
onClick={handleStep3Done}
|
|
345
|
-
className="text-xs px-
|
|
330
|
+
className="text-xs px-2 py-1 rounded-md text-muted-foreground/60 hover:text-muted-foreground hover:bg-muted transition-colors"
|
|
346
331
|
>
|
|
347
332
|
{g.skip}
|
|
348
333
|
</button>
|
|
@@ -353,39 +338,3 @@ export default function GuideCard() {
|
|
|
353
338
|
</div>
|
|
354
339
|
);
|
|
355
340
|
}
|
|
356
|
-
|
|
357
|
-
function TaskCard({ icon, title, cta, done, active, dimmed, onClick }: {
|
|
358
|
-
icon: React.ReactNode;
|
|
359
|
-
title: string;
|
|
360
|
-
cta: string;
|
|
361
|
-
done: boolean;
|
|
362
|
-
active: boolean;
|
|
363
|
-
dimmed?: boolean;
|
|
364
|
-
onClick: () => void;
|
|
365
|
-
}) {
|
|
366
|
-
return (
|
|
367
|
-
<button
|
|
368
|
-
onClick={onClick}
|
|
369
|
-
disabled={done || dimmed}
|
|
370
|
-
className={`
|
|
371
|
-
flex flex-col items-center gap-1.5 px-3 py-3 rounded-lg border text-center
|
|
372
|
-
transition-all duration-150
|
|
373
|
-
${done ? 'opacity-60' : dimmed ? 'opacity-40 cursor-default' : 'hover:border-[var(--amber)]/30 hover:bg-muted/50 cursor-pointer'}
|
|
374
|
-
${active ? 'border-[var(--amber)]/40 bg-muted/50' : ''}
|
|
375
|
-
${done || active ? 'border-[var(--amber)]' : 'border-border'}
|
|
376
|
-
`}
|
|
377
|
-
>
|
|
378
|
-
<span className={`${done ? 'animate-in zoom-in-50 duration-300 text-success' : 'text-[var(--amber)]'}`}>
|
|
379
|
-
{done ? <Check size={16} /> : icon}
|
|
380
|
-
</span>
|
|
381
|
-
<span className="text-xs font-medium text-foreground">
|
|
382
|
-
{title}
|
|
383
|
-
</span>
|
|
384
|
-
{!done && !dimmed && (
|
|
385
|
-
<span className="text-2xs text-[var(--amber-text)]">
|
|
386
|
-
{cta} →
|
|
387
|
-
</span>
|
|
388
|
-
)}
|
|
389
|
-
</button>
|
|
390
|
-
);
|
|
391
|
-
}
|