Skip to content
Open
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
3 changes: 3 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

183 changes: 140 additions & 43 deletions components/sidebar/intersection-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import { useState, useEffect, useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useMapStore } from "@/stores/map-store";
import { X } from "lucide-react";
Expand All @@ -9,19 +10,56 @@ import { PhotoProvider } from "react-photo-view";

export function IntersectionSidebar() {
const { selectedHotspot, selectHotspot } = useMapStore();
const [activeTab, setActiveTab] = useState("overview");
const [direction, setDirection] = useState(1);

// Tab order for directional animations
const tabOrder = ["overview", "audit", "reimagine"];

// Reset to overview tab when hotspot changes
useEffect(() => {
if (selectedHotspot) {
setActiveTab("overview");
setDirection(1);
}
}, [selectedHotspot?.id]);

// Handle tab change
const handleTabChange = (newTab: string) => {
const currentIndex = tabOrder.indexOf(activeTab);
const newIndex = tabOrder.indexOf(newTab);
const newDirection = newIndex > currentIndex ? 1 : -1;
setDirection(newDirection);
setActiveTab(newTab);
};

const variants = {
enter: (direction: number) => ({
x: direction > 0 ? 80 : -80,
opacity: 0,
}),
center: {
x: 0,
opacity: 1,
},
exit: (direction: number) => ({
x: direction < 0 ? 80 : -80,
opacity: 0,
}),
};

return (
<AnimatePresence mode="wait">
{selectedHotspot && (
<motion.aside
key={selectedHotspot.id}
initial={{ x: "100%", opacity: 0 }}
animate={{
x: 0,
animate={{
x: 0,
opacity: 1
}}
exit={{
x: "100%",
exit={{
x: "100%",
opacity: 0
}}
transition={{
Expand All @@ -43,55 +81,114 @@ export function IntersectionSidebar() {
}}
className="flex flex-col h-full"
>
<div className="flex items-center justify-between border-b border-zinc-800 p-4">
<div>
<h2 className="text-lg font-semibold text-white">
{selectedHotspot.intersection}
</h2>
<p className="text-sm text-zinc-400">
{selectedHotspot.total_count} collisions recorded
</p>
</div>
<button
onClick={() => selectHotspot(null)}
className="rounded-lg p-2 hover:bg-zinc-800"
>
<X className="h-5 w-5 text-zinc-400" />
</button>
</div>
<div className="flex items-center justify-between border-b border-zinc-800 p-4">
<div>
<h2 className="text-lg font-semibold text-white">
{selectedHotspot.intersection}
</h2>
<p className="text-sm text-zinc-400">
{selectedHotspot.total_count} collisions recorded
</p>
</div>
<button
onClick={() => selectHotspot(null)}
className="rounded-lg p-2 hover:bg-zinc-800"
>
<X className="h-5 w-5 text-zinc-400" />
</button>
</div>
Comment on lines +93 to +99
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add an accessible label to the icon-only Close button.

Proposed fix
               <button
+                aria-label="Close sidebar"
                 onClick={() => selectHotspot(null)}
                 className="rounded-lg p-2 hover:bg-zinc-800"
               >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
onClick={() => selectHotspot(null)}
className="rounded-lg p-2 hover:bg-zinc-800"
>
<X className="h-5 w-5 text-zinc-400" />
</button>
</div>
<button
aria-label="Close sidebar"
onClick={() => selectHotspot(null)}
className="rounded-lg p-2 hover:bg-zinc-800"
>
<X className="h-5 w-5 text-zinc-400" />
</button>
</div>
🤖 Prompt for AI Agents
In @components/sidebar/intersection-sidebar.tsx around lines 93 - 99, The Close
button is icon-only and lacks an accessible label; update the button that calls
selectHotspot(null) (the element rendering the <X /> icon) to include an
accessible name—e.g., add aria-label="Close" or aria-label="Close hotspot" (or
include a visually hidden <span> with readable text) so screen readers can
announce its purpose; keep the onClick and styling unchanged and ensure the
label conveys the action (Close).


<div className="flex-1 overflow-y-auto p-4">
<PhotoProvider>
<Tabs defaultValue="overview" className="w-full">
<TabsList className="grid w-full grid-cols-3 bg-zinc-900">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="audit">Safety Audit</TabsTrigger>
<TabsTrigger value="reimagine">Re-imagine</TabsTrigger>
</TabsList>
<div className="flex-1 overflow-y-auto p-4 scrollbar-hide [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
<PhotoProvider>
<Tabs value={activeTab} onValueChange={handleTabChange} className="w-full">
<TabsList className="grid w-full grid-cols-3 bg-zinc-900">
<TabsTrigger
value="overview"
className="transition-all hover:scale-105 active:scale-95"
>
Overview
</TabsTrigger>
<TabsTrigger
value="audit"
className="transition-all hover:scale-105 active:scale-95"
>
Safety Audit
</TabsTrigger>
<TabsTrigger
value="reimagine"
className="transition-all hover:scale-105 active:scale-95"
>
Re-imagine
</TabsTrigger>
</TabsList>

<TabsContent value="overview" className="mt-4">
<OverviewTab hotspot={selectedHotspot} />
</TabsContent>
<div className="relative mt-4 overflow-hidden">
<AnimatePresence mode="wait" custom={direction}>
{activeTab === "overview" && (
<motion.div
key="overview"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
style={{ willChange: "transform, opacity" }}
>
<OverviewTab hotspot={selectedHotspot} />
</motion.div>
)}

<TabsContent value="audit" className="mt-4">
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
{activeTab === "audit" && (
<motion.div
key="audit"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4"
style={{ willChange: "transform, opacity" }}
>
<p className="text-sm text-zinc-400">
Generate a safety audit to see AI analysis
</p>
</div>
</TabsContent>
</motion.div>
)}

<TabsContent value="reimagine" className="mt-4">
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
{activeTab === "reimagine" && (
<motion.div
key="reimagine"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4"
style={{ willChange: "transform, opacity" }}
>
<p className="text-sm text-zinc-400">
Re-imagine this intersection with AI
</p>
</div>
</TabsContent>
</Tabs>
</PhotoProvider>
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</div>
</Tabs>
</PhotoProvider>
Comment on lines +103 to +189
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "tabs.tsx" | grep -E "components/ui"

Repository: Lemirq/cision

Length of output: 81


🏁 Script executed:

cat -n ./components/ui/tabs.tsx

Repository: Lemirq/cision

Length of output: 2279


🏁 Script executed:

cat ./package.json | grep -A 2 "@radix-ui/react-tabs"

Repository: Lemirq/cision

Length of output: 171


🏁 Script executed:

head -50 ./components/sidebar/intersection-sidebar.tsx

Repository: Lemirq/cision

Length of output: 1503


🏁 Script executed:

sed -n '103,189p' ./components/sidebar/intersection-sidebar.tsx

Repository: Lemirq/cision

Length of output: 3830


Skip TabsContent breaks ARIA/keyboard semantics; use it to wrap each tab panel instead.

Not using TabsContent removes the role="tabpanel", aria-labelledby, and automatic keyboard navigation that Radix UI provides. The suggested asChild workaround won't work—Radix UI v1.1.13's Content component doesn't support that prop.

Instead, wrap each tab's content directly with TabsContent:

Correct approach
-                  <div className="relative mt-4 overflow-hidden">
-                    <AnimatePresence mode="wait" custom={direction}>
-                      {activeTab === "overview" && (
-                        <motion.div key="overview" ...>
-                          <OverviewTab hotspot={selectedHotspot} />
-                        </motion.div>
-                      )}
-                      ...
-                    </AnimatePresence>
-                  </div>
+                  <AnimatePresence mode="wait" custom={direction}>
+                    <TabsContent value="overview" forceMount className="relative mt-4 overflow-hidden">
+                      {activeTab === "overview" && (
+                        <motion.div key="overview" ...>
+                          <OverviewTab hotspot={selectedHotspot} />
+                        </motion.div>
+                      )}
+                    </TabsContent>
+                    <TabsContent value="audit" forceMount className="relative mt-4 overflow-hidden">
+                      {activeTab === "audit" && (
+                        <motion.div key="audit" ...>
+                          ...
+                        </motion.div>
+                      )}
+                    </TabsContent>
+                    <TabsContent value="reimagine" forceMount className="relative mt-4 overflow-hidden">
+                      {activeTab === "reimagine" && (
+                        <motion.div key="reimagine" ...>
+                          ...
+                        </motion.div>
+                      )}
+                    </TabsContent>
+                  </AnimatePresence>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Tabs value={activeTab} onValueChange={handleTabChange} className="w-full">
<TabsList className="grid w-full grid-cols-3 bg-zinc-900">
<TabsTrigger
value="overview"
className="transition-all hover:scale-105 active:scale-95"
>
Overview
</TabsTrigger>
<TabsTrigger
value="audit"
className="transition-all hover:scale-105 active:scale-95"
>
Safety Audit
</TabsTrigger>
<TabsTrigger
value="reimagine"
className="transition-all hover:scale-105 active:scale-95"
>
Re-imagine
</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="mt-4">
<OverviewTab hotspot={selectedHotspot} />
</TabsContent>
<div className="relative mt-4 overflow-hidden">
<AnimatePresence mode="wait" custom={direction}>
{activeTab === "overview" && (
<motion.div
key="overview"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
style={{ willChange: "transform, opacity" }}
>
<OverviewTab hotspot={selectedHotspot} />
</motion.div>
)}
<TabsContent value="audit" className="mt-4">
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
{activeTab === "audit" && (
<motion.div
key="audit"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4"
style={{ willChange: "transform, opacity" }}
>
<p className="text-sm text-zinc-400">
Generate a safety audit to see AI analysis
</p>
</div>
</TabsContent>
</motion.div>
)}
<TabsContent value="reimagine" className="mt-4">
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
{activeTab === "reimagine" && (
<motion.div
key="reimagine"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4"
style={{ willChange: "transform, opacity" }}
>
<p className="text-sm text-zinc-400">
Re-imagine this intersection with AI
</p>
</div>
</TabsContent>
</Tabs>
</PhotoProvider>
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</div>
</Tabs>
</PhotoProvider>
<Tabs value={activeTab} onValueChange={handleTabChange} className="w-full">
<TabsList className="grid w-full grid-cols-3 bg-zinc-900">
<TabsTrigger
value="overview"
className="transition-all hover:scale-105 active:scale-95"
>
Overview
</TabsTrigger>
<TabsTrigger
value="audit"
className="transition-all hover:scale-105 active:scale-95"
>
Safety Audit
</TabsTrigger>
<TabsTrigger
value="reimagine"
className="transition-all hover:scale-105 active:scale-95"
>
Re-imagine
</TabsTrigger>
</TabsList>
<AnimatePresence mode="wait" custom={direction}>
<TabsContent value="overview" forceMount className="relative mt-4 overflow-hidden">
{activeTab === "overview" && (
<motion.div
key="overview"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
style={{ willChange: "transform, opacity" }}
>
<OverviewTab hotspot={selectedHotspot} />
</motion.div>
)}
</TabsContent>
<TabsContent value="audit" forceMount className="relative mt-4 overflow-hidden">
{activeTab === "audit" && (
<motion.div
key="audit"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
style={{ willChange: "transform, opacity" }}
>
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
<p className="text-sm text-zinc-400">
Generate a safety audit to see AI analysis
</p>
</div>
</motion.div>
)}
</TabsContent>
<TabsContent value="reimagine" forceMount className="relative mt-4 overflow-hidden">
{activeTab === "reimagine" && (
<motion.div
key="reimagine"
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
}}
style={{ willChange: "transform, opacity" }}
>
<div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
<p className="text-sm text-zinc-400">
Re-imagine this intersection with AI
</p>
</div>
</motion.div>
)}
</TabsContent>
</AnimatePresence>
</Tabs>
</PhotoProvider>
🤖 Prompt for AI Agents
In @components/sidebar/intersection-sidebar.tsx around lines 103 - 189, The tab
panels are rendered directly with motion.div which bypasses Radix's TabsContent
and breaks ARIA/keyboard semantics; wrap each panel in TabsContent (using the
matching value prop: "overview", "audit", "reimagine") and put your motion.div
(and its props: key, custom={direction}, variants, initial, animate, exit,
transition, style, className) as the child of that TabsContent (do not use
asChild since Radix v1.1.13 doesn't support it), keeping OverviewTab inside the
"overview" TabsContent and the static <p> nodes inside the corresponding "audit"
and "reimagine" TabsContent so role="tabpanel" and aria-labelledby/keyboard
behavior are restored.

</div>
</motion.div>
</motion.aside>
)}
</AnimatePresence>
Expand Down
48 changes: 35 additions & 13 deletions components/sidebar/persona-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,12 @@ export function PersonaSidebar() {
connectionType: "websocket",
dynamicVariables: selectedHotspot
? {
intersection_name: selectedHotspot.intersection || selectedHotspot.address,
collision_count: selectedHotspot.total_count.toString(),
fatal_count: selectedHotspot.fatal_count.toString(),
cyclist_count: selectedHotspot.cyclist_count.toString(),
pedestrian_count: selectedHotspot.pedestrian_count.toString(),
}
intersection_name: selectedHotspot.intersection || selectedHotspot.address,
collision_count: selectedHotspot.total_count.toString(),
fatal_count: selectedHotspot.fatal_count.toString(),
cyclist_count: selectedHotspot.cyclist_count.toString(),
pedestrian_count: selectedHotspot.pedestrian_count.toString(),
}
: undefined,
});
} catch (error) {
Expand Down Expand Up @@ -247,7 +247,7 @@ export function PersonaSidebar() {
<motion.aside
initial={{ x: 0 }}
animate={{ x: 0 }}
className="fixed left-16 top-0 z-40 h-screen w-80 border-r border-zinc-800 bg-zinc-950 flex flex-col"
className="fixed left-16 top-0 z-40 h-screen w-80 border-r border-zinc-800 bg-zinc-950 flex flex-col overflow-hidden"
>
<AnimatePresence mode="wait">
{currentView === "list" ? (
Expand All @@ -256,6 +256,10 @@ export function PersonaSidebar() {
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{
duration: 0.3,
ease: "easeInOut",
}}
className="flex flex-col h-full"
>
{/* Header */}
Expand All @@ -267,11 +271,18 @@ export function PersonaSidebar() {
</div>

{/* Agent List */}
<div className="flex-1 overflow-y-auto p-4 space-y-3">
{PERSONAS.map((persona) => (
<div className="flex-1 overflow-y-auto p-4 space-y-3 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
{PERSONAS.map((persona, index) => (
<motion.button
key={persona.id}
onClick={() => selectPersona(persona)}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.3,
delay: index * 0.1,
ease: "easeOut",
}}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
className="w-full bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 hover:border-zinc-700 rounded-xl p-4 transition-all text-left group"
Expand Down Expand Up @@ -327,17 +338,23 @@ export function PersonaSidebar() {
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
transition={{
duration: 0.3,
ease: "easeInOut",
}}
className="flex flex-col h-full"
>
{/* Header with Back Button */}
<div className="border-b border-zinc-800 p-4">
<div className="flex items-center gap-3">
<button
<motion.button
onClick={goBack}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className="p-2 -ml-2 hover:bg-zinc-800 rounded-lg transition-colors"
>
<ArrowLeft className="h-5 w-5 text-zinc-400" />
</button>
</motion.button>
Comment on lines +350 to +357
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add an accessible label to the icon-only Back button.

Proposed fix
                 <motion.button
                   onClick={goBack}
+                  aria-label="Back"
                   whileHover={{ scale: 1.1 }}
                   whileTap={{ scale: 0.9 }}
                   className="p-2 -ml-2 hover:bg-zinc-800 rounded-lg transition-colors"
                 >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<motion.button
onClick={goBack}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className="p-2 -ml-2 hover:bg-zinc-800 rounded-lg transition-colors"
>
<ArrowLeft className="h-5 w-5 text-zinc-400" />
</button>
</motion.button>
<motion.button
onClick={goBack}
aria-label="Back"
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className="p-2 -ml-2 hover:bg-zinc-800 rounded-lg transition-colors"
>
<ArrowLeft className="h-5 w-5 text-zinc-400" />
</motion.button>
🤖 Prompt for AI Agents
In @components/sidebar/persona-sidebar.tsx around lines 350 - 357, The Back
button is icon-only (motion.button with onClick={goBack} containing <ArrowLeft
/>) and needs an accessible label; add an aria-label (e.g., aria-label="Go back"
or "Back") to the motion.button or include hidden descriptive text for screen
readers (visually-hidden span) so assistive tech can announce the button purpose
while keeping the icon-only visual; ensure the label is concise and matches the
button action (goBack).

<div className="flex-1">
<h2 className="text-lg font-semibold text-white">
{selectedPersona.name}
Expand All @@ -363,7 +380,7 @@ export function PersonaSidebar() {
</div>

{/* Transcript Area */}
<div className="flex-1 overflow-y-auto p-4 space-y-3">
<div className="flex-1 overflow-y-auto p-4 space-y-3 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
{transcriptMessages.length === 0 && !isCallInProgress && (
<div className="flex flex-col items-center justify-center h-full text-center px-4">
<div
Expand Down Expand Up @@ -441,12 +458,17 @@ export function PersonaSidebar() {
)}

<AnimatePresence initial={false}>
{transcriptMessages.map((message) => (
{transcriptMessages.map((message, index) => (
<motion.div
key={message.id}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0 }}
transition={{
duration: 0.3,
delay: index * 0.05,
ease: "easeOut",
Comment on lines +467 to +470
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Transcript animation delay accumulates unboundedly for long conversations.

The delay: index * 0.05 grows linearly with the transcript length. For a conversation with 50+ messages, new messages will appear with noticeable delays (e.g., 2.5s+ for message 50). Since these are real-time messages, users expect immediate feedback.

Consider removing the index-based delay or using a fixed small delay for all new messages:

Suggested fix
                    transition={{
                      duration: 0.3,
-                     delay: index * 0.05,
+                     delay: 0.05,
                      ease: "easeOut",
                    }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transition={{
duration: 0.3,
delay: index * 0.05,
ease: "easeOut",
transition={{
duration: 0.3,
delay: 0.05,
ease: "easeOut",
🤖 Prompt for AI Agents
In @components/sidebar/persona-sidebar.tsx around lines 467 - 470, The animation
delay currently multiplies the message index (delay: index * 0.05), causing
growing latency for long transcripts; locate the transition prop where delay is
computed (the transition object using duration, delay, ease) and replace the
index-based delay with a fixed small delay or zero (e.g., delay: 0 or delay:
0.05) so new messages render immediately regardless of transcript length while
keeping duration and ease unchanged.

}}
className="space-y-1"
>
<div className="flex items-center gap-2">
Expand Down
6 changes: 1 addition & 5 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
turbopack: {
root: __dirname,
},
};
const nextConfig: NextConfig = {};

export default nextConfig;