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
36 changes: 29 additions & 7 deletions apps/web/app/(app)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"
import type { DocumentsWithMemoriesResponseSchema } from "@repo/validation/api"
import type { z } from "zod"
import { useViewMode } from "@/lib/view-mode-context"
import { ErrorBoundary } from "@/components/error-boundary"
import { cn } from "@lib/utils"
import {
addDocumentParam,
Expand All @@ -42,6 +43,23 @@ import {
type DocumentsResponse = z.infer<typeof DocumentsWithMemoriesResponseSchema>
type DocumentWithMemories = DocumentsResponse["documents"][0]

function ViewErrorFallback() {
return (
<div className="flex-1 flex items-center justify-center p-8">
<p className="text-muted-foreground">
Something went wrong.{" "}
<button
type="button"
className="underline cursor-pointer"
onClick={() => window.location.reload()}
>
Reload
</button>
</p>
</div>
)
}

export default function NewPage() {
const isMobile = useIsMobile()
const { user, session } = useAuth()
Expand Down Expand Up @@ -314,6 +332,7 @@ export default function NewPage() {
)}
>
<div className={cn("relative z-10 flex flex-col md:flex-row h-full")}>
<ErrorBoundary fallback={<ViewErrorFallback />}>
{viewMode === "integrations" ? (
<div className="flex-1 p-4 md:p-6 md:pr-0 pt-2!">
<IntegrationsView />
Expand Down Expand Up @@ -341,15 +360,18 @@ export default function NewPage() {
/>
</div>
)}
</ErrorBoundary>
<div className="hidden md:block md:sticky md:top-0 md:h-screen">
<AnimatePresence mode="popLayout">
<ChatSidebar
isChatOpen={chatOpen}
setIsChatOpen={(open) => setIsChatOpen(open)}
queuedMessage={queuedChatSeed}
onConsumeQueuedMessage={() => setQueuedChatSeed(null)}
emptyStateSuggestions={highlightsData?.questions}
/>
<ErrorBoundary>
<ChatSidebar
isChatOpen={chatOpen}
setIsChatOpen={(open) => setIsChatOpen(open)}
queuedMessage={queuedChatSeed}
onConsumeQueuedMessage={() => setQueuedChatSeed(null)}
emptyStateSuggestions={highlightsData?.questions}
/>
</ErrorBoundary>
</AnimatePresence>
</div>
</div>
Expand Down
25 changes: 21 additions & 4 deletions apps/web/app/(app)/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Account from "@/components/new/settings/account"
import Integrations from "@/components/new/settings/integrations"
import ConnectionsMCP from "@/components/new/settings/connections-mcp"
import Support from "@/components/new/settings/support"
import { ErrorBoundary } from "@/components/error-boundary"
import { useRouter } from "next/navigation"
import { useIsMobile } from "@hooks/use-mobile"
import { analytics } from "@/lib/analytics"
Expand Down Expand Up @@ -248,10 +249,26 @@ export default function SettingsPage() {
</nav>
</div>
<div className="flex-1 flex flex-col gap-4 md:overflow-y-auto md:max-w-2xl [scrollbar-gutter:stable] md:pr-[17px]">
{activeTab === "account" && <Account />}
{activeTab === "integrations" && <Integrations />}
{activeTab === "connections" && <ConnectionsMCP />}
{activeTab === "support" && <Support />}
<ErrorBoundary
key={activeTab}
fallback={
<p className="text-muted-foreground p-4">
Something went wrong loading this section.{" "}
<button
type="button"
className="underline cursor-pointer"
onClick={() => window.location.reload()}
>
Reload
</button>
</p>
}
>
{activeTab === "account" && <Account />}
{activeTab === "integrations" && <Integrations />}
{activeTab === "connections" && <ConnectionsMCP />}
{activeTab === "support" && <Support />}
</ErrorBoundary>
</div>
</div>
</main>
Expand Down
33 changes: 33 additions & 0 deletions apps/web/components/error-boundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"use client"

import { Component, type ReactNode } from "react"

interface Props {
children: ReactNode
fallback?: ReactNode
onError?: (error: Error, errorInfo: React.ErrorInfo) => void
}

interface State {
error: Error | null
}

export class ErrorBoundary extends Component<Props, State> {
override state: State = { error: null }

static getDerivedStateFromError(error: Error): State {
return { error }
}

override componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
this.props.onError?.(error, errorInfo)
console.error("[ErrorBoundary]", error, errorInfo)
}

override render() {
if (this.state.error) {
return this.props.fallback ?? null
}
return this.props.children
}
}
2 changes: 1 addition & 1 deletion apps/web/components/new/add-document/connections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function ConnectContent({ selectedProject }: ConnectContentProps) {
useEffect(() => {
if (!autumn.isLoading) {
setIsProUser(
autumn.customer?.products.some((product) => product.id === "api_pro") ??
autumn.customer?.products?.some((product) => product.id === "api_pro") ??
false,
)
}
Expand Down
12 changes: 11 additions & 1 deletion apps/web/components/new/chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,17 @@ export function ChatSidebar({

const { messages, sendMessage, status, setMessages, stop } = useChat({
id: currentChatId ?? undefined,
transport: chatTransport,
transport: new DefaultChatTransport({
api: `${process.env.NEXT_PUBLIC_BACKEND_URL ?? "https://api.supermemory.ai"}/chat/v2`,
credentials: "include",
body: {
metadata: {
chatId: currentChatId,
projectId: selectedProject,
model: selectedModel,
},
},
}),
onFinish: async (result) => {
if (result.message.role !== "assistant") return

Expand Down
1 change: 1 addition & 0 deletions apps/web/components/new/document-cards/tweet-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function CustomTweetHeader({
tweet: ReturnType<typeof enrichTweet>
}) {
const user = tweet.user
if (!user) return null
const isVerified = user.verified || user.is_blue_verified

return (
Expand Down
15 changes: 9 additions & 6 deletions apps/web/components/new/memories-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { z } from "zod"
import { Masonry, useInfiniteLoader } from "masonic"
import { dmSansClassName } from "@/lib/fonts"
import { SuperLoader } from "@/components/superloader"
import { ErrorBoundary } from "@/components/error-boundary"
import { cn } from "@lib/utils"
import { useProject } from "@/stores"
import { useIsMobile } from "@hooks/use-mobile"
Expand Down Expand Up @@ -254,12 +255,14 @@ export function MemoriesGrid({
}) => {
if (data.type === "document") {
return (
<DocumentCard
index={index}
data={data.data}
width={width}
onClick={handleCardClick}
/>
<ErrorBoundary>
<DocumentCard
index={index}
data={data.data}
width={width}
onClick={handleCardClick}
/>
</ErrorBoundary>
)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/lib/posthog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {

useEffect(() => {
if (typeof window !== "undefined") {
const posthogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY
const posthogKey = "phc_uO09ylgCPmQl3wHukVvvwhphtoIaGmCMUTTwDo3PRlt"
const backendUrl =
process.env.NEXT_PUBLIC_BACKEND_URL ?? "https://api.supermemory.ai"

Expand Down
Loading