feat(admin): add Compose and Settings tabs to Harvest Reach communications
- Add Compose tab that displays CampaignComposerPage with 4-step wizard - Add Settings tab linking to existing /admin/communications/settings - Complete the 8-tab navigation structure for Harvest Reach module Tabs: Campaigns, Compose, Segments, Analytics, Templates, Contacts, Logs, Settings
This commit is contained in:
@@ -8,6 +8,7 @@ const TABS = [
|
|||||||
{ id: "templates", label: "Templates" },
|
{ id: "templates", label: "Templates" },
|
||||||
{ id: "contacts", label: "Contacts" },
|
{ id: "contacts", label: "Contacts" },
|
||||||
{ id: "logs", label: "Logs" },
|
{ id: "logs", label: "Logs" },
|
||||||
|
{ id: "settings", label: "Settings" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// Icon components
|
// Icon components
|
||||||
@@ -81,7 +82,7 @@ const Icons = {
|
|||||||
export default function CommunicationsNav({
|
export default function CommunicationsNav({
|
||||||
activeTab,
|
activeTab,
|
||||||
}: {
|
}: {
|
||||||
activeTab: "campaigns" | "templates" | "contacts" | "logs" | "segments" | "analytics" | "compose";
|
activeTab: "campaigns" | "templates" | "contacts" | "logs" | "segments" | "analytics" | "compose" | "settings";
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<nav className="grid grid-cols-4 sm:grid-cols-7 gap-1 p-1.5 rounded-xl bg-white border border-stone-200">
|
<nav className="grid grid-cols-4 sm:grid-cols-7 gap-1 p-1.5 rounded-xl bg-white border border-stone-200">
|
||||||
@@ -104,6 +105,7 @@ export default function CommunicationsNav({
|
|||||||
{tab.id === "templates" && Icons.fileText("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
{tab.id === "templates" && Icons.fileText("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
||||||
{tab.id === "contacts" && Icons.userCheck("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
{tab.id === "contacts" && Icons.userCheck("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
||||||
{tab.id === "logs" && Icons.list("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
{tab.id === "logs" && Icons.list("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
||||||
|
{tab.id === "settings" && Icons.settings("h-3.5 w-3.5 sm:h-4 sm:w-4")}
|
||||||
<span>{tab.label}</span>
|
<span>{tab.label}</span>
|
||||||
{isActive && (
|
{isActive && (
|
||||||
<div className="absolute bottom-1 sm:bottom-1.5 left-1/2 -translate-x-1/2 h-0.5 w-4 sm:w-8 bg-white rounded-full" />
|
<div className="absolute bottom-1 sm:bottom-1.5 left-1/2 -translate-x-1/2 h-0.5 w-4 sm:w-8 bg-white rounded-full" />
|
||||||
|
|||||||
@@ -16,7 +16,14 @@ import type { Contact } from "@/actions/communications/contacts";
|
|||||||
import type { Segment } from "@/actions/harvest-reach/segments";
|
import type { Segment } from "@/actions/harvest-reach/segments";
|
||||||
import type { CampaignAnalytics } from "@/actions/harvest-reach/campaigns";
|
import type { CampaignAnalytics } from "@/actions/harvest-reach/campaigns";
|
||||||
|
|
||||||
type Tab = "campaigns" | "templates" | "contacts" | "segments" | "logs" | "analytics";
|
type Tab = "campaigns" | "compose" | "templates" | "contacts" | "segments" | "logs" | "analytics";
|
||||||
|
|
||||||
|
const ComposeIcon = () => (
|
||||||
|
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
|
||||||
|
<polyline points="22,6 12,13 2,6"/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
const MailIcon = () => (
|
const MailIcon = () => (
|
||||||
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
@@ -119,6 +126,7 @@ export default function CommunicationsPage({
|
|||||||
}}
|
}}
|
||||||
tabs={[
|
tabs={[
|
||||||
{ value: "campaigns", label: "Campaigns", icon: <MailIcon /> },
|
{ value: "campaigns", label: "Campaigns", icon: <MailIcon /> },
|
||||||
|
{ value: "compose", label: "Compose", icon: <ComposeIcon /> },
|
||||||
{ value: "templates", label: "Templates", icon: <FileTextIcon /> },
|
{ value: "templates", label: "Templates", icon: <FileTextIcon /> },
|
||||||
{ value: "contacts", label: "Contacts", icon: <UsersIcon /> },
|
{ value: "contacts", label: "Contacts", icon: <UsersIcon /> },
|
||||||
{ value: "segments", label: "Segments", icon: <LayersIcon /> },
|
{ value: "segments", label: "Segments", icon: <LayersIcon /> },
|
||||||
@@ -198,8 +206,20 @@ export default function CommunicationsPage({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Compose Mode */}
|
{/* Compose Tab */}
|
||||||
{(isComposing || editCampaignId) && (
|
{currentTab === "compose" && (
|
||||||
|
<div className="rounded-2xl border border-[var(--admin-border)] bg-white">
|
||||||
|
<CampaignComposerPage
|
||||||
|
brandId={brandId}
|
||||||
|
campaigns={campaigns}
|
||||||
|
templates={templates}
|
||||||
|
segments={initialSegments}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Legacy Compose Mode (from edit mode) */}
|
||||||
|
{(isComposing || editCampaignId) && currentTab === "campaigns" && (
|
||||||
<div className="rounded-2xl border border-[var(--admin-border)] bg-white">
|
<div className="rounded-2xl border border-[var(--admin-border)] bg-white">
|
||||||
<CampaignComposerPage
|
<CampaignComposerPage
|
||||||
brandId={brandId}
|
brandId={brandId}
|
||||||
|
|||||||
Reference in New Issue
Block a user