Seth commited on
Commit ·
a13ea2b
1
Parent(s): 84525e6
update
Browse files
frontend/src/pages/EmailSequenceGenerator.jsx
CHANGED
|
@@ -1,27 +1,31 @@
|
|
| 1 |
import React, { useState } from 'react';
|
|
|
|
| 2 |
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
| 3 |
import AppShell from '@/components/layout/AppShell';
|
| 4 |
-
import EmailGeneratorTab from '@/components/campaigns/EmailGeneratorTab';
|
| 5 |
import LinkedinCampaignsTab from '@/components/campaigns/LinkedinCampaignsTab';
|
| 6 |
import CampaignsDashboardTab from '@/components/campaigns/CampaignsDashboardTab';
|
|
|
|
| 7 |
|
| 8 |
export default function EmailSequenceGenerator() {
|
| 9 |
-
const [activeTab, setActiveTab] = useState('
|
| 10 |
|
| 11 |
return (
|
| 12 |
<AppShell
|
| 13 |
title="Campaigns"
|
| 14 |
subtitle="Create and run email + LinkedIn campaigns from one workspace."
|
| 15 |
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
| 17 |
<TabsList className="mb-6 flex-wrap gap-1">
|
| 18 |
-
<TabsTrigger value="generator">Email/AI Generator</TabsTrigger>
|
| 19 |
-
<TabsTrigger value="linkedin">LinkedIn Campaigns</TabsTrigger>
|
| 20 |
<TabsTrigger value="campaigns">Campaigns</TabsTrigger>
|
|
|
|
| 21 |
</TabsList>
|
| 22 |
-
<TabsContent value="generator">
|
| 23 |
-
<EmailGeneratorTab />
|
| 24 |
-
</TabsContent>
|
| 25 |
<TabsContent value="linkedin">
|
| 26 |
<LinkedinCampaignsTab />
|
| 27 |
</TabsContent>
|
|
|
|
| 1 |
import React, { useState } from 'react';
|
| 2 |
+
import { Link } from 'react-router-dom';
|
| 3 |
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
| 4 |
import AppShell from '@/components/layout/AppShell';
|
|
|
|
| 5 |
import LinkedinCampaignsTab from '@/components/campaigns/LinkedinCampaignsTab';
|
| 6 |
import CampaignsDashboardTab from '@/components/campaigns/CampaignsDashboardTab';
|
| 7 |
+
import { Button } from '@/components/ui/button';
|
| 8 |
|
| 9 |
export default function EmailSequenceGenerator() {
|
| 10 |
+
const [activeTab, setActiveTab] = useState('campaigns');
|
| 11 |
|
| 12 |
return (
|
| 13 |
<AppShell
|
| 14 |
title="Campaigns"
|
| 15 |
subtitle="Create and run email + LinkedIn campaigns from one workspace."
|
| 16 |
>
|
| 17 |
+
<p className="mb-4 text-sm text-slate-600">
|
| 18 |
+
Upload contacts, configure prompts, and export sequences from{' '}
|
| 19 |
+
<Button variant="link" className="h-auto p-0 text-violet-700" asChild>
|
| 20 |
+
<Link to="/settings">Settings → Email / AI generator</Link>
|
| 21 |
+
</Button>
|
| 22 |
+
.
|
| 23 |
+
</p>
|
| 24 |
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
| 25 |
<TabsList className="mb-6 flex-wrap gap-1">
|
|
|
|
|
|
|
| 26 |
<TabsTrigger value="campaigns">Campaigns</TabsTrigger>
|
| 27 |
+
<TabsTrigger value="linkedin">LinkedIn Campaigns</TabsTrigger>
|
| 28 |
</TabsList>
|
|
|
|
|
|
|
|
|
|
| 29 |
<TabsContent value="linkedin">
|
| 30 |
<LinkedinCampaignsTab />
|
| 31 |
</TabsContent>
|
frontend/src/pages/Settings.jsx
CHANGED
|
@@ -1,14 +1,17 @@
|
|
| 1 |
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
| 2 |
import {
|
|
|
|
| 3 |
ClipboardCopy,
|
| 4 |
Loader2,
|
| 5 |
ShieldAlert,
|
| 6 |
Link2,
|
|
|
|
| 7 |
UserPlus,
|
| 8 |
Users,
|
| 9 |
Trash2,
|
| 10 |
} from 'lucide-react';
|
| 11 |
import AppShell from '@/components/layout/AppShell';
|
|
|
|
| 12 |
import LinkedInConnectSettings from '@/components/settings/LinkedInConnectSettings';
|
| 13 |
import ConnectMailboxSettings from '@/components/settings/ConnectMailboxSettings';
|
| 14 |
import { Button } from '@/components/ui/button';
|
|
@@ -24,6 +27,8 @@ import { apiFetch } from '@/lib/api';
|
|
| 24 |
import { cn } from '@/lib/utils';
|
| 25 |
|
| 26 |
export default function Settings() {
|
|
|
|
|
|
|
| 27 |
const [me, setMe] = useState(null);
|
| 28 |
const [meLoading, setMeLoading] = useState(true);
|
| 29 |
const [members, setMembers] = useState([]);
|
|
@@ -186,13 +191,37 @@ export default function Settings() {
|
|
| 186 |
);
|
| 187 |
}
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
return (
|
| 190 |
<AppShell
|
| 191 |
title="Settings"
|
| 192 |
subtitle={
|
| 193 |
isAdmin
|
| 194 |
-
? 'Invitations, members, LinkedIn, mailbox,
|
| 195 |
-
: 'LinkedIn, mailbox,
|
| 196 |
}
|
| 197 |
>
|
| 198 |
<div className="space-y-8 max-w-3xl">
|
|
@@ -359,6 +388,20 @@ export default function Settings() {
|
|
| 359 |
<LinkedInConnectSettings />
|
| 360 |
<ConnectMailboxSettings />
|
| 361 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
<section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
|
| 363 |
<div className="flex items-center gap-2 text-slate-800 font-semibold mb-4">
|
| 364 |
<Link2 className="h-5 w-5 text-violet-600" />
|
|
|
|
| 1 |
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
| 2 |
import {
|
| 3 |
+
ArrowLeft,
|
| 4 |
ClipboardCopy,
|
| 5 |
Loader2,
|
| 6 |
ShieldAlert,
|
| 7 |
Link2,
|
| 8 |
+
Sparkles,
|
| 9 |
UserPlus,
|
| 10 |
Users,
|
| 11 |
Trash2,
|
| 12 |
} from 'lucide-react';
|
| 13 |
import AppShell from '@/components/layout/AppShell';
|
| 14 |
+
import EmailGeneratorTab from '@/components/campaigns/EmailGeneratorTab';
|
| 15 |
import LinkedInConnectSettings from '@/components/settings/LinkedInConnectSettings';
|
| 16 |
import ConnectMailboxSettings from '@/components/settings/ConnectMailboxSettings';
|
| 17 |
import { Button } from '@/components/ui/button';
|
|
|
|
| 27 |
import { cn } from '@/lib/utils';
|
| 28 |
|
| 29 |
export default function Settings() {
|
| 30 |
+
/** 'main' | 'email_generator' — full-page generator inside Settings */
|
| 31 |
+
const [settingsPanel, setSettingsPanel] = useState('main');
|
| 32 |
const [me, setMe] = useState(null);
|
| 33 |
const [meLoading, setMeLoading] = useState(true);
|
| 34 |
const [members, setMembers] = useState([]);
|
|
|
|
| 191 |
);
|
| 192 |
}
|
| 193 |
|
| 194 |
+
if (settingsPanel === 'email_generator') {
|
| 195 |
+
return (
|
| 196 |
+
<AppShell
|
| 197 |
+
title="Settings"
|
| 198 |
+
subtitle="Email / AI generator — upload contacts, prompts, and export."
|
| 199 |
+
>
|
| 200 |
+
<div className="w-full max-w-6xl">
|
| 201 |
+
<div className="mb-6 flex flex-wrap items-center gap-3">
|
| 202 |
+
<Button
|
| 203 |
+
type="button"
|
| 204 |
+
variant="outline"
|
| 205 |
+
className="gap-2"
|
| 206 |
+
onClick={() => setSettingsPanel('main')}
|
| 207 |
+
>
|
| 208 |
+
<ArrowLeft className="h-4 w-4" aria-hidden />
|
| 209 |
+
Back to settings
|
| 210 |
+
</Button>
|
| 211 |
+
</div>
|
| 212 |
+
<EmailGeneratorTab />
|
| 213 |
+
</div>
|
| 214 |
+
</AppShell>
|
| 215 |
+
);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
return (
|
| 219 |
<AppShell
|
| 220 |
title="Settings"
|
| 221 |
subtitle={
|
| 222 |
isAdmin
|
| 223 |
+
? 'Invitations, members, LinkedIn, mailbox, Smartlead webhook, and email generator.'
|
| 224 |
+
: 'LinkedIn, mailbox, Smartlead webhook, and email generator. Invites and member management require admin.'
|
| 225 |
}
|
| 226 |
>
|
| 227 |
<div className="space-y-8 max-w-3xl">
|
|
|
|
| 388 |
<LinkedInConnectSettings />
|
| 389 |
<ConnectMailboxSettings />
|
| 390 |
|
| 391 |
+
<section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
|
| 392 |
+
<div className="flex items-center gap-2 text-slate-800 font-semibold mb-2">
|
| 393 |
+
<Sparkles className="h-5 w-5 text-violet-600" />
|
| 394 |
+
Email / AI generator
|
| 395 |
+
</div>
|
| 396 |
+
<p className="text-sm text-slate-600 mb-4">
|
| 397 |
+
Import an Apollo CSV, choose products, edit prompts, and generate email sequences in
|
| 398 |
+
a guided flow. Opens full width here so you can focus on the tool.
|
| 399 |
+
</p>
|
| 400 |
+
<Button type="button" onClick={() => setSettingsPanel('email_generator')}>
|
| 401 |
+
Open Email / AI generator
|
| 402 |
+
</Button>
|
| 403 |
+
</section>
|
| 404 |
+
|
| 405 |
<section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
|
| 406 |
<div className="flex items-center gap-2 text-slate-800 font-semibold mb-4">
|
| 407 |
<Link2 className="h-5 w-5 text-violet-600" />
|