lots of changes
This commit is contained in:
@@ -98,8 +98,8 @@ export function SectionEditor({
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-3">
|
||||
<CardTitle className="text-base">{title}</CardTitle>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-2 px-4 py-3">
|
||||
<CardTitle className="text-sm">{title}</CardTitle>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Button variant="outline" size="sm" onClick={() => setIsAddOpen(true)}>
|
||||
Add
|
||||
@@ -109,17 +109,17 @@ export function SectionEditor({
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2 text-sm">
|
||||
<CardContent className="max-h-[260px] space-y-2 overflow-auto px-4 pb-4 text-xs">
|
||||
{items.length === 0 ? (
|
||||
<div className="text-muted-foreground">No items yet.</div>
|
||||
) : (
|
||||
items.map((item, index) => (
|
||||
<div
|
||||
key={`${sectionKey}-${index}`}
|
||||
className="flex flex-wrap items-start justify-between gap-2 rounded-md border border-border/60 p-3"
|
||||
className="flex flex-wrap items-start justify-between gap-2 rounded-md border border-border/60 p-2"
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<div className="font-medium">{summarizeItem(item)}</div>
|
||||
<div className="space-y-1">
|
||||
<div className="font-medium text-sm">{summarizeItem(item)}</div>
|
||||
<Badge variant="outline">#{index + 1}</Badge>
|
||||
</div>
|
||||
<Button
|
||||
@@ -246,8 +246,8 @@ export function ProfileSectionEditor({
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-3">
|
||||
<CardTitle className="text-base">Product Profile</CardTitle>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-2 px-4 py-3">
|
||||
<CardTitle className="text-sm">Product Profile</CardTitle>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Button variant="outline" size="sm" onClick={() => setIsEditOpen(true)}>
|
||||
Edit
|
||||
@@ -257,7 +257,7 @@ export function ProfileSectionEditor({
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2 text-sm text-muted-foreground">
|
||||
<CardContent className="max-h-[260px] space-y-2 overflow-auto px-4 pb-4 text-xs text-muted-foreground">
|
||||
<div>
|
||||
<span className="font-medium text-foreground">Product:</span>{" "}
|
||||
{items.productName || "Not set"}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Settings,
|
||||
Terminal,
|
||||
Target,
|
||||
Inbox,
|
||||
Plus,
|
||||
ArrowUpRight,
|
||||
ChevronsUpDown
|
||||
@@ -87,6 +88,10 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
const [pendingSourceId, setPendingSourceId] = React.useState<string | null>(null);
|
||||
const [pendingProjectId, setPendingProjectId] = React.useState<string | null>(null);
|
||||
const [pendingJobId, setPendingJobId] = React.useState<string | null>(null);
|
||||
const sourceUrlRef = React.useRef<HTMLInputElement | null>(null);
|
||||
const sourceNameRef = React.useRef<HTMLInputElement | null>(null);
|
||||
const manualProductNameRef = React.useRef<HTMLInputElement | null>(null);
|
||||
const manualDescriptionRef = React.useRef<HTMLTextAreaElement | null>(null);
|
||||
const analysisJob = useQuery(
|
||||
api.analysisJobs.getById,
|
||||
pendingJobId ? { jobId: pendingJobId as any } : "skip"
|
||||
@@ -189,18 +194,20 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
throw new Error(data.error || "Analysis failed");
|
||||
}
|
||||
|
||||
await createAnalysis({
|
||||
projectId: result.projectId,
|
||||
dataSourceId: result.sourceId,
|
||||
analysis: data.data,
|
||||
});
|
||||
if (!data.persisted) {
|
||||
await createAnalysis({
|
||||
projectId: result.projectId,
|
||||
dataSourceId: result.sourceId,
|
||||
analysis: data.data,
|
||||
});
|
||||
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: result.sourceId,
|
||||
analysisStatus: "completed",
|
||||
lastError: undefined,
|
||||
lastAnalyzedAt: Date.now(),
|
||||
});
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: result.sourceId,
|
||||
analysisStatus: "completed",
|
||||
lastError: undefined,
|
||||
lastAnalyzedAt: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
setSourceUrl("");
|
||||
setSourceName("");
|
||||
@@ -258,18 +265,20 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
throw new Error(data.error || "Manual analysis failed");
|
||||
}
|
||||
|
||||
await createAnalysis({
|
||||
projectId: pendingProjectId as any,
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysis: data.data,
|
||||
});
|
||||
if (!data.persisted) {
|
||||
await createAnalysis({
|
||||
projectId: pendingProjectId as any,
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysis: data.data,
|
||||
});
|
||||
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysisStatus: "completed",
|
||||
lastError: undefined,
|
||||
lastAnalyzedAt: Date.now(),
|
||||
});
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysisStatus: "completed",
|
||||
lastError: undefined,
|
||||
lastAnalyzedAt: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
setSourceUrl("");
|
||||
setSourceName("");
|
||||
@@ -288,6 +297,20 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputEnter = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>,
|
||||
next?: React.RefObject<HTMLElement>,
|
||||
onSubmit?: () => void
|
||||
) => {
|
||||
if (event.key !== "Enter" || isSubmittingSource) return;
|
||||
event.preventDefault();
|
||||
if (next?.current) {
|
||||
next.current.focus();
|
||||
return;
|
||||
}
|
||||
onSubmit?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<Sidebar variant="inset" {...props}>
|
||||
<SidebarHeader>
|
||||
@@ -365,9 +388,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip="Overview"
|
||||
isActive={pathname === "/dashboard"}
|
||||
isActive={pathname === "/app/dashboard"}
|
||||
>
|
||||
<Link href="/dashboard">
|
||||
<Link href="/app/dashboard">
|
||||
<Terminal />
|
||||
<span>Overview</span>
|
||||
</Link>
|
||||
@@ -377,9 +400,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip="Search"
|
||||
isActive={pathname === "/opportunities"}
|
||||
isActive={pathname === "/app/search"}
|
||||
>
|
||||
<Link href="/opportunities">
|
||||
<Link href="/app/search">
|
||||
<Target />
|
||||
<span>Search</span>
|
||||
</Link>
|
||||
@@ -389,9 +412,10 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip="Inbox"
|
||||
isActive={pathname === "/leads"}
|
||||
isActive={pathname === "/app/inbox"}
|
||||
>
|
||||
<Link href="/leads" className="pl-8 text-sm text-muted-foreground hover:text-foreground">
|
||||
<Link href="/app/inbox">
|
||||
<Inbox />
|
||||
<span>Inbox</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
@@ -431,7 +455,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
</Label>
|
||||
</div>
|
||||
<Link
|
||||
href={`/data-sources/${source._id}`}
|
||||
href={`/app/data-sources/${source._id}`}
|
||||
className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
Details
|
||||
@@ -508,7 +532,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
placeholder="https://example.com"
|
||||
value={sourceUrl}
|
||||
onChange={(event) => setSourceUrl(event.target.value)}
|
||||
onKeyDown={(event) => handleInputEnter(event, sourceNameRef)}
|
||||
disabled={isSubmittingSource}
|
||||
ref={sourceUrlRef}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
@@ -518,7 +544,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
placeholder="Product name"
|
||||
value={sourceName}
|
||||
onChange={(event) => setSourceName(event.target.value)}
|
||||
onKeyDown={(event) => handleInputEnter(event, undefined, handleAddSource)}
|
||||
disabled={isSubmittingSource}
|
||||
ref={sourceNameRef}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@@ -531,7 +559,9 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
id="manualProductName"
|
||||
value={manualProductName}
|
||||
onChange={(event) => setManualProductName(event.target.value)}
|
||||
onKeyDown={(event) => handleInputEnter(event, manualDescriptionRef)}
|
||||
disabled={isSubmittingSource}
|
||||
ref={manualProductNameRef}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
@@ -542,6 +572,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
onChange={(event) => setManualDescription(event.target.value)}
|
||||
disabled={isSubmittingSource}
|
||||
rows={3}
|
||||
ref={manualDescriptionRef}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -23,7 +23,7 @@ export function SignIn() {
|
||||
try {
|
||||
const flow = step === "signIn" ? "signIn" : "signUp";
|
||||
await signIn("password", { email, password, flow });
|
||||
const next = nextPath || (flow === "signIn" ? "/dashboard" : "/onboarding");
|
||||
const next = nextPath || (flow === "signIn" ? "/app/dashboard" : "/onboarding");
|
||||
if (flow === "signIn") {
|
||||
router.push(next);
|
||||
} else {
|
||||
@@ -41,7 +41,7 @@ export function SignIn() {
|
||||
};
|
||||
|
||||
const handleGoogleSignIn = () => {
|
||||
const next = nextPath || "/dashboard";
|
||||
const next = nextPath || "/app/dashboard";
|
||||
void signIn("google", { redirectTo: next });
|
||||
};
|
||||
|
||||
|
||||
@@ -100,24 +100,24 @@ export function NavUser({
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => router.push("/settings?tab=upgrade")}>
|
||||
<DropdownMenuItem onSelect={() => router.push("/app/settings?tab=upgrade")}>
|
||||
<Sparkles />
|
||||
Upgrade to Pro
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => router.push("/settings?tab=account")}>
|
||||
<DropdownMenuItem onSelect={() => router.push("/app/settings?tab=account")}>
|
||||
<BadgeCheck />
|
||||
Account
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onSelect={() => router.push("/settings?tab=billing")}>
|
||||
<DropdownMenuItem onSelect={() => router.push("/app/settings?tab=billing")}>
|
||||
<CreditCard />
|
||||
Billing
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onSelect={() => router.push("/help")}>
|
||||
<DropdownMenuItem onSelect={() => router.push("/app/help")}>
|
||||
<HelpCircle />
|
||||
Support
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -24,8 +24,8 @@ export function Sidebar({ productName }: SidebarProps) {
|
||||
{
|
||||
label: 'Overview',
|
||||
icon: LayoutDashboard,
|
||||
href: '/dashboard',
|
||||
active: pathname === '/dashboard',
|
||||
href: '/app/dashboard',
|
||||
active: pathname === '/app/dashboard',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -68,10 +68,10 @@ export function Sidebar({ productName }: SidebarProps) {
|
||||
</Link>
|
||||
))}
|
||||
<Link
|
||||
href="/opportunities"
|
||||
href="/app/search"
|
||||
className={cn(
|
||||
'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
||||
pathname === '/opportunities'
|
||||
pathname === '/app/search'
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
|
||||
)}
|
||||
@@ -80,10 +80,10 @@ export function Sidebar({ productName }: SidebarProps) {
|
||||
Search
|
||||
</Link>
|
||||
<Link
|
||||
href="/leads"
|
||||
href="/app/inbox"
|
||||
className={cn(
|
||||
'flex items-center rounded-md px-3 py-2 pl-9 text-sm font-medium transition-colors',
|
||||
pathname === '/leads'
|
||||
pathname === '/app/inbox'
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user