Add active outreach funnel dashboard

This commit is contained in:
jjbrunton committed 2026-08-09 15:54:05 +01:00
1 parent deaf86c364
commit f55ae7ddf8
15 files changed
+519 -1

No files matched your search

+38 -1
View File
@@ -79,7 +79,7 @@ describe('dashboard foundation', () => {
const { router } = renderDashboard('/');
const navigation = screen.getByRole('navigation', { name: 'Primary navigation' });
for (const label of ['Overview', 'Needs attention', 'Conversations', 'Media', 'Performance', 'Operations', 'Settings']) {
for (const label of ['Overview', 'Needs attention', 'Outreach funnel', 'Conversations', 'Media', 'Performance', 'Operations', 'Settings']) {
expect(within(navigation).getByRole('link', { name: label })).toBeInTheDocument();
}
@@ -109,6 +109,43 @@ describe('dashboard foundation', () => {
expect(screen.getByRole('link', { name: 'Open conversation' })).toHaveAttribute('href', '/conversations/%40one%3Areddit.com~!room%3Areddit.com');
});
it('shows the live outreach stages and the potential posts being burned down', async () => {
installSuccessfulApi();
server.use(
http.get('/api/login/status', () => HttpResponse.json({ ready: true, loggedIn: true, status: 'authenticated' })),
http.get('/api/chats/sync', () => HttpResponse.json({
syncing: false, syncingKind: null, lastFullSyncAt: null, lastDeltaSyncAt: null,
hasEverFullSynced: false, cachedChats: 0, progress: null,
})),
http.get('/api/outreach', () => HttpResponse.json({
generatedAt: Date.parse('2026-08-09T08:00:00Z'),
activeCount: 3,
stages: { discovered: 1, screening: 0, ready: 1, sending: 0, retryable: 1 },
outcomes: { sent: 12, rejected: 7 },
oldestActiveAt: Date.parse('2026-08-09T07:00:00Z'),
candidates: [{
postId: 'candidate-1', subreddit: 'example', author: 'alice', title: '[25F] A potential post',
postUrl: 'https://www.reddit.com/r/example/comments/candidate-1/', sourceType: 'image',
status: 'ready', priority: 2, postCreatedAt: Date.parse('2026-08-09T06:50:00Z'),
discoveredAt: Date.parse('2026-08-09T07:00:00Z'), updatedAt: Date.parse('2026-08-09T07:30:00Z'),
availableAt: Date.parse('2026-08-09T07:30:00Z'), attemptCount: 1, hasPreparedMessage: true,
note: null, owner: null,
}],
})),
);
renderDashboard('/outreach');
expect(await screen.findByRole('heading', { name: 'Outreach funnel' })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: '3 active posts' })).toBeInTheDocument();
expect(screen.getByRole('list', { name: 'Active outreach candidates' })).toHaveTextContent('A potential post');
expect(screen.getByRole('link', { name: '[25F] A potential post' })).toHaveAttribute(
'href',
'https://www.reddit.com/r/example/comments/candidate-1/',
);
expect(within(screen.getByRole('list', { name: 'Active outreach candidates' })).getByText('Message prepared')).toBeInTheDocument();
});
it('hydrates media filters from the routed URL', async () => {
installSuccessfulApi();
server.use(