feat: fix the Steps tab still pointing at /sequences and replace remaining user-facing Sequences with Steps (route page + folder renamed to steps, document title regex, permission labels, not-found hint, campaign count)

This commit is contained in:
Matthew Meszaros
2026-06-12 10:03:02 +02:00
parent aba0878833
commit eb74b7dafb
8 changed files with 15 additions and 15 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ import { usePresenceResource } from "@/hooks/PresenceProvider";
const TABS = [
{ label: "Overview", path: "", Icon: BarChart3Icon },
{ label: "Leads", path: "/leads", Icon: UsersIcon },
{ label: "Steps", path: "/sequences", Icon: ListChecksIcon },
{ label: "Steps", path: "/steps", Icon: ListChecksIcon },
{ label: "Schedule", path: "/schedule", Icon: CalendarIcon },
{ label: "Settings", path: "/preferences", Icon: Settings2Icon },
] as const;
@@ -9,20 +9,20 @@ import useCreateSequence from "@/lib/api/hooks/app/campaigns/sequences/useCreate
import type { AppError } from "@/lib/api/client/normalizeError";
import buildError from "@/lib/helper/buildError";
export default function CampaignSequences() {
export default function CampaignSteps() {
const campaign = useCampaign();
if (!campaign) {
throw new Error("CampaignSequences cannot be rendered without a campaign");
throw new Error("CampaignSteps cannot be rendered without a campaign");
}
return (
<React.Suspense fallback={<SequencesSkeleton />}>
<SequencesBuilder campaignId={campaign.id} />
<React.Suspense fallback={<StepsSkeleton />}>
<StepsBuilder campaignId={campaign.id} />
</React.Suspense>
);
}
function SequencesBuilder({ campaignId }: { campaignId: string }) {
function StepsBuilder({ campaignId }: { campaignId: string }) {
const { data: sequences } = useSequences(campaignId);
const createSequence = useCreateSequence(campaignId);
const [creating, setCreating] = React.useState(false);
@@ -74,6 +74,6 @@ function SequencesBuilder({ campaignId }: { campaignId: string }) {
return <CampaignFlow campaignId={campaignId} />;
}
function SequencesSkeleton() {
function StepsSkeleton() {
return <div className="h-[74dvh] w-full animate-pulse rounded-md border border-slate-200 bg-slate-100/60" />;
}
+1 -1
View File
@@ -324,7 +324,7 @@ export default function CampaignsPage() {
? "Loading…"
: campaignsData.isError
? "Failed to load"
: `${campaigns.length} ${campaigns.length === 1 ? "sequence" : "sequences"}`
: `${campaigns.length} ${campaigns.length === 1 ? "campaign" : "campaigns"}`
}
>
<TopbarAction
+1 -1
View File
@@ -16,7 +16,7 @@ import { cn } from "@/lib/utils";
const dests = [
{ title: "Accounts", url: "/app/emails", icon: MailIcon, hint: "mailboxes & senders" },
{ title: "Campaigns", url: "/app/campaigns", icon: MegaphoneIcon, hint: "sequences & sends" },
{ title: "Campaigns", url: "/app/campaigns", icon: MegaphoneIcon, hint: "steps & sends" },
{ title: "Contacts", url: "/app/contacts", icon: UsersIcon, hint: "people & lists" },
{ title: "Analytics", url: "/app/analytics", icon: BarChart3Icon, hint: "opens, clicks, replies" },
];
+1 -1
View File
@@ -74,7 +74,7 @@ const PARAM_ROUTES: ReadonlyArray<readonly [RegExp, string]> = [
[/^\/app\/campaigns\/[^/]+\/leads$/, "Campaign leads"],
[/^\/app\/campaigns\/[^/]+\/preferences$/, "Campaign settings"],
[/^\/app\/campaigns\/[^/]+\/schedule$/, "Campaign schedule"],
[/^\/app\/campaigns\/[^/]+\/sequences$/, "Campaign sequences"],
[/^\/app\/campaigns\/[^/]+\/steps$/, "Campaign steps"],
[/^\/app\/campaigns\/[^/]+$/, "Campaign"],
[/^\/app\/admin\/workers\/[^/]+$/, "Worker"],
];
+1 -1
View File
@@ -26,7 +26,7 @@ export const PERMISSION_LABELS: Record<PermissionKey, string> = {
VIEW_ANALYTICS: "View analytics",
SEND_CAMPAIGNS: "Send campaigns",
ACCESS_UNIBOX: "Use unified inbox",
MANAGE_SEQUENCES: "Manage sequences",
MANAGE_SEQUENCES: "Manage steps",
MANAGE_SETTINGS: "Manage settings",
VIEW_CAMPAIGNS: "View campaigns",
VIEW_CONTACTS: "View contacts",
+2 -2
View File
@@ -39,11 +39,11 @@ export interface PermissionDef {
export const PERMISSION_CATALOG: PermissionDef[] = [
// Data
{ key: "VIEW_CAMPAIGNS", bit: PERMISSION_BITS.VIEW_CAMPAIGNS, label: "View campaigns", description: "Read campaign settings, sequences, and analytics.", category: "data" },
{ key: "VIEW_CAMPAIGNS", bit: PERMISSION_BITS.VIEW_CAMPAIGNS, label: "View campaigns", description: "Read campaign settings, steps, and analytics.", category: "data" },
{ key: "MANAGE_CAMPAIGNS", bit: PERMISSION_BITS.MANAGE_CAMPAIGNS, label: "Manage campaigns", description: "Create, edit and archive campaigns.", category: "data" },
{ key: "VIEW_CONTACTS", bit: PERMISSION_BITS.VIEW_CONTACTS, label: "View contacts", description: "Read contacts, segments and tags.", category: "data" },
{ key: "MANAGE_CONTACTS", bit: PERMISSION_BITS.MANAGE_CONTACTS, label: "Manage contacts", description: "Create, edit and delete contacts.", category: "data" },
{ key: "MANAGE_SEQUENCES", bit: PERMISSION_BITS.MANAGE_SEQUENCES, label: "Manage sequences", description: "Edit step content + spacing inside a campaign.", category: "data" },
{ key: "MANAGE_SEQUENCES", bit: PERMISSION_BITS.MANAGE_SEQUENCES, label: "Manage steps", description: "Edit step content + spacing inside a campaign.", category: "data" },
{ key: "VIEW_ANALYTICS", bit: PERMISSION_BITS.VIEW_ANALYTICS, label: "View analytics", description: "See deliverability + engagement reports.", category: "data" },
{ key: "USE_INTEGRATIONS", bit: PERMISSION_BITS.USE_INTEGRATIONS, label: "Use integrations", description: "Push contacts and deals to connected CRMs and tools.", category: "data" },
// People
+2 -2
View File
@@ -18,7 +18,7 @@ import CampaignPreview from './app/app/campaigns/[id]/page';
import CampaignLeads from './app/app/campaigns/[id]/leads/page';
import CampaignPreferences from './app/app/campaigns/[id]/preferences/page';
import CampaignSchedule from './app/app/campaigns/[id]/schedule/page';
import CampaignSequences from './app/app/campaigns/[id]/sequences/page';
import CampaignSteps from './app/app/campaigns/[id]/steps/page';
import AnalyticsPage from './app/app/analytics/page';
import DeliverabilityPage from './app/app/deliverability/page';
import PipelinesPage from './app/app/crm/pipelines/page';
@@ -230,7 +230,7 @@ const router = createBrowserRouter([
},
{
path: "steps",
element: <CampaignSequences />,
element: <CampaignSteps />,
}
]
}