Add frontend campaign create/list to backlinkOutreachApi + store + component
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { fetchBacklinkQueryTemplates } from '../../api/backlinkOutreachApi';
|
||||
import { useBacklinkOutreachStore } from '../../stores/backlinkOutreachStore';
|
||||
|
||||
const BacklinkOutreachModuleList: React.FC = () => {
|
||||
const { modules, coverage, isLoading, error, refreshBacklinkRegistry } = useBacklinkOutreachStore();
|
||||
const { modules, coverage, campaigns, isLoading, error, refreshBacklinkRegistry, fetchCampaigns, createCampaign } = useBacklinkOutreachStore();
|
||||
const [queryPreview, setQueryPreview] = useState<string[]>([]);
|
||||
const [newCampaignName, setNewCampaignName] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
refreshBacklinkRegistry();
|
||||
@@ -19,6 +20,16 @@ const BacklinkOutreachModuleList: React.FC = () => {
|
||||
loadPreview().catch(() => setQueryPreview([]));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCampaigns('default', 'default').catch(() => {});
|
||||
}, [fetchCampaigns]);
|
||||
|
||||
const handleCreateCampaign = useCallback(async () => {
|
||||
if (!newCampaignName.trim()) return;
|
||||
await createCampaign('default', 'default', newCampaignName.trim());
|
||||
setNewCampaignName('');
|
||||
}, [newCampaignName, createCampaign]);
|
||||
|
||||
return (
|
||||
<section>
|
||||
<h3>Backlink Outreach Modules</h3>
|
||||
@@ -51,6 +62,31 @@ const BacklinkOutreachModuleList: React.FC = () => {
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
|
||||
<h4>Campaigns</h4>
|
||||
{campaigns.length === 0 ? (
|
||||
<p>No campaigns yet. Create one below.</p>
|
||||
) : (
|
||||
<ul>
|
||||
{campaigns.map((c) => (
|
||||
<li key={c.campaign_id}>
|
||||
<strong>{c.name}</strong> ({c.status})
|
||||
{c.created_at && <span> — {new Date(c.created_at).toLocaleDateString()}</span>}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
value={newCampaignName}
|
||||
onChange={(e) => setNewCampaignName(e.target.value)}
|
||||
placeholder="Campaign name"
|
||||
/>
|
||||
<button onClick={handleCreateCampaign} disabled={!newCampaignName.trim()}>
|
||||
Create Campaign
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user