Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 86d906e

Browse files
committed
Wizard integration and first data-less tasks
1 parent e2819da commit 86d906e

12 files changed

Lines changed: 1113 additions & 2 deletions

File tree

‎apps/code/src/renderer/components/MainLayout.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { InboxView } from "@features/inbox/components/InboxView";
1010
import { FolderSettingsView } from "@features/settings/components/FolderSettingsView";
1111
import { SettingsDialog } from "@features/settings/components/SettingsDialog";
1212
import { useSettingsDialogStore } from "@features/settings/stores/settingsDialogStore";
13+
import { SetupView } from "@features/setup/components/SetupView";
1314
import { MainSidebar } from "@features/sidebar/components/MainSidebar";
1415
import { SkillsView } from "@features/skills/components/SkillsView";
1516
import { TaskDetail } from "@features/task-detail/components/TaskDetail";
@@ -97,6 +98,8 @@ export function MainLayout() {
9798
{view.type === "command-center" && <CommandCenterView />}
9899

99100
{view.type === "skills" && <SkillsView />}
101+
102+
{view.type === "setup" && <SetupView />}
100103
</Box>
101104
</Flex>
102105

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import { ArrowLeft, ArrowRight } from "@phosphor-icons/react";
2+
import { Button, Flex, Text } from "@radix-ui/themes";
3+
import explorerHog from "@renderer/assets/images/hedgehogs/explorer-hog.png";
4+
import { AnimatePresence, motion } from "framer-motion";
5+
import { useEffect, useState } from "react";
6+
7+
import { useContextCollection } from "../hooks/useContextCollection";
8+
import { SourceFeed } from "./context-collection/SourceFeed";
9+
import { SuggestedTasks } from "./context-collection/SuggestedTasks";
10+
import { StepActions } from "./StepActions";
11+
12+
interface ContextCollectionStepProps {
13+
onNext: () => void;
14+
onBack: () => void;
15+
}
16+
17+
export function ContextCollectionStep({
18+
onNext,
19+
onBack,
20+
}: ContextCollectionStepProps) {
21+
const { sources, phase, isAllDone, totalItems } = useContextCollection();
22+
const [showTasks, setShowTasks] = useState(false);
23+
24+
// Delay showing tasks briefly after scanning completes for a smooth transition
25+
useEffect(() => {
26+
if (!isAllDone) return;
27+
const timeout = setTimeout(() => setShowTasks(true), 800);
28+
return () => clearTimeout(timeout);
29+
}, [isAllDone]);
30+
31+
return (
32+
<Flex
33+
align="center"
34+
height="100%"
35+
px="8"
36+
style={{ position: "relative", zIndex: 1 }}
37+
>
38+
<Flex
39+
direction="column"
40+
align="center"
41+
style={{
42+
width: "100%",
43+
height: "100%",
44+
paddingTop: 24,
45+
paddingBottom: 40,
46+
}}
47+
>
48+
{/* Content area */}
49+
<Flex
50+
direction="column"
51+
justify="center"
52+
style={{ flex: 1, minHeight: 0, overflowY: "auto" }}
53+
>
54+
<Flex
55+
direction="column"
56+
gap="5"
57+
style={{
58+
width: "100%",
59+
minWidth: 520,
60+
maxWidth: 520,
61+
margin: "0 auto",
62+
backgroundColor: "var(--color-panel-translucent)",
63+
borderRadius: 16,
64+
padding: "24px 28px",
65+
}}
66+
>
67+
<AnimatePresence mode="wait">
68+
{!showTasks ? (
69+
<motion.div
70+
key="scanning"
71+
exit={{ opacity: 0, y: -12 }}
72+
transition={{ duration: 0.3 }}
73+
>
74+
<Flex direction="column" gap="5">
75+
{/* Title */}
76+
<motion.div
77+
initial={{ opacity: 0, y: 8 }}
78+
animate={{ opacity: 1, y: 0 }}
79+
transition={{ duration: 0.3 }}
80+
>
81+
<Flex direction="column" gap="2">
82+
<Text
83+
size="6"
84+
weight="bold"
85+
style={{
86+
color: "var(--gray-12)",
87+
lineHeight: 1.3,
88+
}}
89+
>
90+
Building your context...
91+
</Text>
92+
<Text size="2" style={{ color: "var(--gray-11)" }}>
93+
Scanning your data sources for insights and
94+
priorities.
95+
</Text>
96+
</Flex>
97+
</motion.div>
98+
99+
{/* Source feed */}
100+
<motion.div
101+
initial={{ opacity: 0, y: 8 }}
102+
animate={{ opacity: 1, y: 0 }}
103+
transition={{ duration: 0.3, delay: 0.05 }}
104+
>
105+
<SourceFeed sources={sources} />
106+
</motion.div>
107+
108+
{/* Phase status + hedgehog */}
109+
<motion.div
110+
initial={{ opacity: 0, y: 8 }}
111+
animate={{ opacity: 1, y: 0 }}
112+
transition={{ duration: 0.3, delay: 0.1 }}
113+
>
114+
<Flex align="center" gap="3" py="2">
115+
<img
116+
src={explorerHog}
117+
alt=""
118+
style={{
119+
width: 40,
120+
height: 40,
121+
objectFit: "contain",
122+
flexShrink: 0,
123+
}}
124+
/>
125+
<AnimatePresence mode="wait">
126+
<motion.div
127+
key={phase}
128+
initial={{ opacity: 0, y: 4 }}
129+
animate={{ opacity: 1, y: 0 }}
130+
exit={{ opacity: 0, y: -4 }}
131+
transition={{ duration: 0.2 }}
132+
>
133+
<Text
134+
size="2"
135+
style={{
136+
color: isAllDone
137+
? "var(--green-11)"
138+
: "var(--gray-11)",
139+
fontStyle: isAllDone ? "normal" : "italic",
140+
}}
141+
>
142+
{phase}
143+
{isAllDone && (
144+
<Text
145+
size="2"
146+
style={{
147+
color: "var(--gray-9)",
148+
marginLeft: 8,
149+
}}
150+
>
151+
{totalItems.toLocaleString()} items across{" "}
152+
{sources.length} sources
153+
</Text>
154+
)}
155+
</Text>
156+
</motion.div>
157+
</AnimatePresence>
158+
</Flex>
159+
</motion.div>
160+
</Flex>
161+
</motion.div>
162+
) : (
163+
<motion.div
164+
key="tasks"
165+
initial={{ opacity: 0, y: 12 }}
166+
animate={{ opacity: 1, y: 0 }}
167+
transition={{ duration: 0.4 }}
168+
>
169+
<Flex direction="column" gap="5">
170+
{/* Title */}
171+
<Flex direction="column" gap="2">
172+
<Text
173+
size="6"
174+
weight="bold"
175+
style={{
176+
color: "var(--gray-12)",
177+
lineHeight: 1.3,
178+
}}
179+
>
180+
Here's what we found
181+
</Text>
182+
<Text size="2" style={{ color: "var(--gray-11)" }}>
183+
Based on {totalItems.toLocaleString()} items across your
184+
data sources, we recommend starting with one of these:
185+
</Text>
186+
</Flex>
187+
188+
{/* Task cards */}
189+
<SuggestedTasks onSelectTask={() => onNext()} />
190+
</Flex>
191+
</motion.div>
192+
)}
193+
</AnimatePresence>
194+
</Flex>
195+
</Flex>
196+
197+
{/* Footer buttons */}
198+
<StepActions>
199+
<Button size="3" variant="outline" color="gray" onClick={onBack}>
200+
<ArrowLeft size={16} weight="bold" />
201+
Back
202+
</Button>
203+
<AnimatePresence>
204+
{showTasks && (
205+
<motion.div
206+
initial={{ opacity: 0, y: 4 }}
207+
animate={{ opacity: 1, y: 0 }}
208+
transition={{ duration: 0.3, delay: 0.3 }}
209+
>
210+
<Button size="3" variant="ghost" onClick={onNext}>
211+
Skip for now
212+
<ArrowRight size={16} weight="bold" />
213+
</Button>
214+
</motion.div>
215+
)}
216+
</AnimatePresence>
217+
</StepActions>
218+
</Flex>
219+
</Flex>
220+
);
221+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Flex } from "@radix-ui/themes";
2+
import type { SourceState } from "../../hooks/useContextCollection";
3+
4+
import { SourceSlot } from "./SourceSlot";
5+
6+
interface SourceFeedProps {
7+
sources: SourceState[];
8+
}
9+
10+
export function SourceFeed({ sources }: SourceFeedProps) {
11+
return (
12+
<Flex direction="column" gap="2" style={{ width: "100%" }}>
13+
{sources.map((source) => (
14+
<SourceSlot key={source.config.id} source={source} />
15+
))}
16+
</Flex>
17+
);
18+
}

0 commit comments

Comments
 (0)