Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {
"@elysiajs/cors": "^1.4.1",
"@t3-oss/env-core": "^0.13.10",
"convex": "^1.31.7",
"convex": "^1.32.0",
"jose": "^6.1.3",
"jsonwebtoken": "^9.0.3",
"zod": "^3.25.76"
Expand Down
2 changes: 1 addition & 1 deletion apps/application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@mentra/sdk": "^2.1.29",
"@t3-oss/env-core": "^0.13.10",
"@tavily/core": "^0.5.14",
"convex": "^1.31.7",
"convex": "^1.32.0",
"exa-js": "^1.10.2",
"openai": "^5.23.2",
"zod": "^3.25.76"
Expand Down
22 changes: 11 additions & 11 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,30 @@
"@vercel/analytics": "^1.6.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"convex": "^1.31.7",
"convex": "^1.32.0",
"date-fns": "^4.1.0",
"framer-motion": "^12.34.0",
"framer-motion": "^12.34.3",
"lucide-react": "^0.553.0",
"mapbox-gl": "^3.18.1",
"motion": "^12.34.0",
"mapbox-gl": "^3.19.0",
"motion": "^12.34.3",
"react": "^19.2.4",
"react-day-picker": "^9.13.2",
"react-day-picker": "^9.14.0",
"react-dom": "^19.2.4",
"react-map-gl": "^8.1.0",
"react-router-dom": "^7.13.0",
"react-router-dom": "^7.13.1",
"recharts": "^3.7.0",
"tailwind-merge": "^3.4.0",
"tailwind-merge": "^3.5.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.18",
"@types/node": "^24.10.13",
"@tailwindcss/vite": "^4.2.1",
"@types/node": "^24.10.15",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^4.7.0",
"autoprefixer": "^10.4.24",
"autoprefixer": "^10.4.27",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.18",
"tailwindcss": "^4.2.1",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/ChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function ChatPage({ mentraUserId }: ChatPageProps) {
useEffect(() => {
if (existingMessages && pendingMessages.length > 0) {
const existingContents = new Set(
existingMessages.map((m) => `${m.role}:${m.content}`),
existingMessages.map((m: Message) => `${m.role}:${m.content}`),
);
const remaining = pendingMessages.filter(
(m) => !existingContents.has(`${m.role}:${m.content}`),
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/FollowupChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function FollowupChatPage({ mentraUserId }: FollowupChatPageProps) {
useEffect(() => {
if (existingMessages && pendingMessages.length > 0) {
const existingContents = new Set(
existingMessages.map((m) => `${m.role}:${m.content}`),
existingMessages.map((m: Message) => `${m.role}:${m.content}`),
);
const remaining = pendingMessages.filter(
(m) => !existingContents.has(`${m.role}:${m.content}`),
Expand Down
96 changes: 52 additions & 44 deletions apps/web/src/components/FollowupsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,52 +125,60 @@ export function FollowupsPage({ userId }: FollowupsPageProps) {
<h2 className="text-xl font-semibold">Follow-ups</h2>

<div className="space-y-4">
{followups.map((followup) => (
<Card
key={followup._id}
className={followup.status === "pending" ? "cursor-pointer" : ""}
onClick={() => {
if (followup.status === "pending") {
navigate(`/followups/chat/${followup._id}`);
}
}}
>
<CardHeader className="pb-2">
<div className="flex items-center justify-between gap-2">
<CardTitle className="text-lg">{followup.topic}</CardTitle>
<StatusBadge status={followup.status} />
</div>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-foreground text-sm">{followup.summary}</p>
{followups.map(
(followup: {
_id: Id<"followups">;
topic: string;
summary: string;
status: "pending" | "completed" | "dismissed";
createdAt: string;
}) => (
<Card
key={followup._id}
className={followup.status === "pending" ? "cursor-pointer" : ""}
onClick={() => {
if (followup.status === "pending") {
navigate(`/followups/chat/${followup._id}`);
}
}}
>
<CardHeader className="pb-2">
<div className="flex items-center justify-between gap-2">
<CardTitle className="text-lg">{followup.topic}</CardTitle>
<StatusBadge status={followup.status} />
</div>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-foreground text-sm">{followup.summary}</p>

<div className="flex items-center justify-between">
<p className="text-xs text-foreground/50">
{formatRelativeTime(followup.createdAt)}
</p>
<div className="flex items-center justify-between">
<p className="text-xs text-foreground/50">
{formatRelativeTime(followup.createdAt)}
</p>

{followup.status === "pending" && (
<div className="flex gap-2">
<Button
variant="neutral"
size="sm"
onClick={(e) => handleComplete(followup._id, e)}
>
Complete
</Button>
<Button
variant="neutral"
size="sm"
onClick={(e) => handleDismiss(followup._id, e)}
>
Dismiss
</Button>
</div>
)}
</div>
</CardContent>
</Card>
))}
{followup.status === "pending" && (
<div className="flex gap-2">
<Button
variant="neutral"
size="sm"
onClick={(e) => handleComplete(followup._id, e)}
>
Complete
</Button>
<Button
variant="neutral"
size="sm"
onClick={(e) => handleDismiss(followup._id, e)}
>
Dismiss
</Button>
</div>
)}
</div>
</CardContent>
</Card>
),
)}
</div>
</div>
);
Expand Down
71 changes: 39 additions & 32 deletions apps/web/src/components/MemoryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,40 +82,47 @@ export function MemoryPage({ mentraUserId }: MemoryPageProps) {
<h2 className="text-xl font-semibold">Memory</h2>

<div className="space-y-4">
{result.summaries.map((day) => (
<Card
key={day.date}
className="cursor-pointer"
onClick={() => navigate(`/memory/chat/${day.date}`)}
>
<CardHeader className="pb-2">
<CardTitle className="text-lg flex items-center gap-2">
<span>📅</span>
{formatDate(day.date)}
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-foreground">{day.summary}</p>
{result.summaries.map(
(day: {
date: string;
summary: string;
topics: string[];
sessionCount: number;
}) => (
<Card
key={day.date}
className="cursor-pointer"
onClick={() => navigate(`/memory/chat/${day.date}`)}
>
<CardHeader className="pb-2">
<CardTitle className="text-lg flex items-center gap-2">
<span>📅</span>
{formatDate(day.date)}
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-foreground">{day.summary}</p>

{day.topics.length > 0 && (
<div className="flex flex-wrap gap-2">
{day.topics.map((topic) => (
<span
key={topic}
className="px-2 py-1 bg-main/10 text-main rounded-base text-sm border border-main/20"
>
{topic}
</span>
))}
</div>
)}
{day.topics.length > 0 && (
<div className="flex flex-wrap gap-2">
{day.topics.map((topic: string) => (
<span
key={topic}
className="px-2 py-1 bg-main/10 text-main rounded-base text-sm border border-main/20"
>
{topic}
</span>
))}
</div>
)}

<p className="text-xs text-foreground/50">
{day.sessionCount} session{day.sessionCount > 1 ? "s" : ""}
</p>
</CardContent>
</Card>
))}
<p className="text-xs text-foreground/50">
{day.sessionCount} session{day.sessionCount > 1 ? "s" : ""}
</p>
</CardContent>
</Card>
),
)}
</div>
</div>
);
Expand Down
Loading