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
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import { useSidebar } from "@/components/ui/sidebar";
import { MessageCircleIcon } from "lucide-react";

export function AIChatButton() {
const { setOpen } = useSidebar();
const { setOpen, setOpenMobile, isMobile } = useSidebar();

return (
<Button
size="sm"
variant="outline"
onClick={() => setOpen((arr) => [...arr, "chat-sidebar"])}
onClick={() => {
setOpen((arr) => [...arr, "chat-sidebar"]);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Nov 8, 2025

Choose a reason for hiding this comment

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

Unconditionally calling setOpen here means mobile usage permanently flags "chat-sidebar" as open in the desktop state/cookie, so the right sidebar reopens on desktop after mobile users close it. Please only update setOpen when not on mobile.

Prompt for AI agents
Address the following comment on apps/web/app/(app)/[emailAccountId]/assistant/AIChatButton.tsx at line 15:

<comment>Unconditionally calling setOpen here means mobile usage permanently flags &quot;chat-sidebar&quot; as open in the desktop state/cookie, so the right sidebar reopens on desktop after mobile users close it. Please only update setOpen when not on mobile.</comment>

<file context>
@@ -12,8 +12,10 @@ export function AIChatButton() {
       onClick={() =&gt; {
-        const setter = isMobile ? setOpenMobile : setOpen;
-        setter((arr) =&gt; [...arr, &quot;chat-sidebar&quot;]);
+        setOpen((arr) =&gt; [...arr, &quot;chat-sidebar&quot;]);
+        if (isMobile) {
+          setOpenMobile((arr) =&gt; [...arr, &quot;chat-sidebar&quot;]);
</file context>
Fix with Cubic

if (isMobile) {
setOpenMobile((arr) => [...arr, "chat-sidebar"]);
}
}}
>
<MessageCircleIcon className="mr-2 size-4" />
AI Chat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const actionTooltips: Partial<Record<ActionType, string>> = {
export function AvailableActionsPanel() {
const { provider } = useAccount();
return (
<Card className="h-fit bg-slate-50 dark:bg-slate-900">
<Card className="h-fit bg-slate-50 dark:bg-slate-900 hidden sm:block">
Comment thread
elie222 marked this conversation as resolved.
<CardContent className="pt-4">
<div className="grid gap-2">
<ActionSection
Expand Down
100 changes: 50 additions & 50 deletions apps/web/app/(app)/[emailAccountId]/assistant/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,8 @@ import {
import { DEFAULT_COLD_EMAIL_PROMPT } from "@/utils/cold-email/prompt";

export function Rules({
size = "md",
showAddRuleButton = true,
}: {
size?: "sm" | "md";
showAddRuleButton?: boolean;
}) {
const { data, isLoading, error, mutate } = useRules();
Expand Down Expand Up @@ -143,11 +141,13 @@ export function Rules({
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-16">Enabled</TableHead>
<TableHead>Name</TableHead>
{size === "md" && <TableHead>Condition</TableHead>}
<TableHead>Action</TableHead>
<TableHead>
<TableHead className="w-16 px-2 sm:px-4">Enabled</TableHead>
<TableHead className="px-2 sm:px-4">Name</TableHead>
<TableHead className="hidden sm:table-cell px-2 sm:px-4">
Condition
</TableHead>
<TableHead className="px-2 sm:px-4">Action</TableHead>
<TableHead className="px-2 sm:px-4">
{showAddRuleButton && (
<div className="flex justify-end">
<div className="my-2">
Expand Down Expand Up @@ -186,7 +186,7 @@ export function Rules({
>
<TableCell
onClick={(e) => e.stopPropagation()}
className="text-center"
className="text-center p-2 sm:p-4"
>
<Switch
size="sm"
Expand Down Expand Up @@ -227,53 +227,53 @@ export function Rules({
}}
/>
</TableCell>
<TableCell className="font-medium">{rule.name}</TableCell>
{size === "md" && (
<TableCell>
{(() => {
const systemRuleDesc = getSystemRuleDescription(
rule.systemType,
);
if (isConversationStatus) {
return (
<div className="flex items-center gap-2">
<span className="text-sm text-muted-foreground">
{systemRuleDesc?.condition || ""}
</span>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon className="size-3.5 text-green-600 dark:text-green-500 flex-shrink-0 cursor-help" />
</TooltipTrigger>
<TooltipContent
side="right"
className="max-w-xs"
>
<p>
System rule to track conversation
status. Conditions cannot be edited.
</p>
</TooltipContent>
</Tooltip>
</div>
);
}
<TableCell className="font-medium p-2 sm:p-4">
{rule.name}
</TableCell>
<TableCell className="hidden sm:table-cell p-2 sm:p-4">
{(() => {
const systemRuleDesc = getSystemRuleDescription(
rule.systemType,
);
if (isConversationStatus) {
return (
<ExpandableText
text={conditionsToString(rule)}
className="max-w-xs"
/>
<div className="flex items-center gap-2">
<span className="text-sm text-muted-foreground">
{systemRuleDesc?.condition || ""}
</span>
<Tooltip>
<TooltipTrigger asChild>
<InfoIcon className="size-3.5 text-green-600 dark:text-green-500 flex-shrink-0 cursor-help" />
</TooltipTrigger>
<TooltipContent
side="right"
className="max-w-xs"
>
<p>
System rule to track conversation status.
Conditions cannot be edited.
</p>
</TooltipContent>
</Tooltip>
</div>
);
})()}
</TableCell>
)}
<TableCell>
}
return (
<ExpandableText
text={conditionsToString(rule)}
className="max-w-xs"
/>
);
})()}
</TableCell>
<TableCell className="p-2 sm:p-4">
<ActionBadges
actions={rule.actions}
provider={provider}
labels={userLabels}
/>
</TableCell>
<TableCell className="text-center">
<TableCell className="text-center p-2 sm:p-4">
{!isPlaceholder && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand Down Expand Up @@ -434,17 +434,17 @@ export function ActionBadges({
labels: Array<{ id: string; name: string }>;
}) {
return (
<div className="flex gap-2 flex-wrap">
<div className="flex gap-2 flex-wrap min-w-0">
{sortActionsByPriority(actions).map((action) => {
const Icon = getActionIcon(action.type);

return (
<Badge
key={action.id}
color={getActionColor(action.type)}
className="w-fit text-nowrap"
className="w-fit sm:text-nowrap shrink-0"
>
<Icon className="size-3 mr-1.5" />
<Icon className="size-3 mr-1.5 hidden sm:block" />
{getActionDisplay(action, provider, labels)}
</Badge>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function RulesPromptForm({
/>
</LoadingContent>

<div className="flex flex-wrap gap-2">
<div className="flex flex-col sm:flex-row flex-wrap gap-2">
<Button type="submit" size="sm" loading={isSubmitting}>
Create rules
</Button>
Expand All @@ -190,7 +190,7 @@ function RulesPromptForm({
</Button>

<Button
className="ml-auto"
className="ml-auto w-full sm:w-auto"
variant="outline"
size="sm"
onClick={() => ruleDialog.onOpen()}
Expand Down
14 changes: 0 additions & 14 deletions apps/web/app/(app)/[emailAccountId]/compose/page.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function CategoryCard({
<IconCircle size="sm" color={iconColor} Icon={Icon} />
<div>
{useTooltip ? (
<div className="flex flex-1 items-center gap-2">
<div className="flex flex-1 items-center gap-2 text-sm sm:text-base">
{label}
{description && (
<TooltipExplanation
Expand Down Expand Up @@ -256,9 +256,9 @@ function CategoryCard({
<>
<SelectItem value="label">Categorise</SelectItem>
<SelectItem value="move_folder">Move to folder</SelectItem>
<SelectItem value="move_folder_delayed">
{/* <SelectItem value="move_folder_delayed">
Move to folder after a week
</SelectItem>
</SelectItem> */}
</>
)}
{isGoogleProvider(provider) && (
Expand All @@ -267,9 +267,9 @@ function CategoryCard({
<SelectItem value="label_archive">
Label & skip inbox
</SelectItem>
<SelectItem value="label_archive_delayed">
{/* <SelectItem value="label_archive_delayed">
Label & archive after a week
</SelectItem>
</SelectItem> */}
</>
)}
<SelectItem value="none">Do nothing</SelectItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function OnboardingWrapper({
className,
)}
>
<div className="mx-auto flex max-w-6xl flex-col justify-center space-y-6 p-10 duration-500 animate-in fade-in">
<div className="mx-auto flex max-w-6xl flex-col justify-center space-y-6 p-4 sm:p-10 duration-500 animate-in fade-in">
{children}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function StepCustomRules({
<div className="rounded-2xl p-4 bg-slate-50 border border-slate-200">
<Image
src="/images/onboarding/custom-rules.png"
alt="Draft replies"
alt="Custom rules"
width={1200}
height={800}
className="rounded-xl border border-slate-200"
Expand Down
8 changes: 4 additions & 4 deletions apps/web/app/(app)/[emailAccountId]/onboarding/StepIntro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export function StepIntro({ onNext }: { onNext: () => void }) {
<div className="text-center mt-4">
<PageHeading>Get to know Inbox Zero</PageHeading>
<TypographyP className="mt-2 max-w-lg mx-auto">
Here are the basics of Inbox Zero. We'll take you through the steps to
get you started and set you up for success.
We'll take you through the steps to get you started and set you up for
success.
</TypographyP>
</div>
<div className="mt-8">
<div className="grid gap-8">
<div className="grid gap-4 sm:gap-8">
<Benefit
index={1}
title="Emails sorted automatically"
Expand Down Expand Up @@ -73,7 +73,7 @@ function Benefit({
<div className="flex items-center gap-4 col-span-2">
<IconCircle>{index}</IconCircle>
<div>
<div className="font-semibold text-xl">{title}</div>
<div className="font-semibold text-lg sm:text-xl">{title}</div>
<div className="text-sm text-muted-foreground mt-1 leading-6">
<p>{description}</p>
</div>
Expand Down
12 changes: 7 additions & 5 deletions apps/web/app/(app)/[emailAccountId]/usage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getUsage } from "@/utils/redis/usage";
import { TopSection } from "@/components/TopSection";
import { Usage } from "@/app/(app)/[emailAccountId]/usage/usage";
import { auth } from "@/utils/auth";
import {
Expand All @@ -9,6 +8,8 @@ import {
import { checkUserOwnsEmailAccount } from "@/utils/email-account";
import { notFound } from "next/navigation";
import prisma from "@/utils/prisma";
import { PageWrapper } from "@/components/PageWrapper";
import { PageHeader } from "@/components/PageHeader";

export default async function UsagePage(props: {
params: Promise<{ emailAccountId: string }>;
Expand Down Expand Up @@ -53,17 +54,18 @@ export default async function UsagePage(props: {
const isOwnAccount = emailAccount.user.id === userId;

return (
<div>
<TopSection
<PageWrapper>
<PageHeader
title={
isOwnAccount
? "Credits and Usage"
: `Credits and Usage for ${emailAccount.name || emailAccount.email}`
}
description=""
/>
<div className="m-4">
<div className="my-4">
<Usage usage={usage} />
</div>
</div>
</PageWrapper>
);
}
11 changes: 6 additions & 5 deletions apps/web/app/(app)/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AdminUpgradeUserForm } from "@/app/(app)/admin/AdminUpgradeUserForm";
import { AdminUserControls } from "@/app/(app)/admin/AdminUserControls";
import { TopSection } from "@/components/TopSection";
import { auth } from "@/utils/auth";
import { ErrorPage } from "@/components/ErrorPage";
import { isAdmin } from "@/utils/admin";
Expand All @@ -12,6 +11,8 @@ import { RegisterSSOModal } from "@/app/(app)/admin/RegisterSSOModal";
import { AdminHashEmail } from "@/app/(app)/admin/AdminHashEmail";
import { GmailUrlConverter } from "@/app/(app)/admin/GmailUrlConverter";
import { DebugLabels } from "@/app/(app)/admin/DebugLabels";
import { PageWrapper } from "@/components/PageWrapper";
import { PageHeader } from "@/components/PageHeader";

// NOTE: Turn on Fluid Compute on Vercel to allow for 800 seconds max duration
export const maxDuration = 800;
Expand All @@ -29,10 +30,10 @@ export default async function AdminPage() {
}

return (
<div>
<TopSection title="Admin" />
<PageWrapper>
<PageHeader title="Admin" description="" />

<div className="m-8 space-y-8">
<div className="space-y-8 mt-4 mb-20">
<AdminUpgradeUserForm />
<AdminUserControls />
<AdminHashEmail />
Expand All @@ -45,6 +46,6 @@ export default async function AdminPage() {
<AdminSyncStripeCustomers />
</div>
</div>
</div>
</PageWrapper>
);
}
Loading
Loading