+
+ {currentBrand?.display_name || selected.brand_id}
+ {selected.seed_query ? 種子:{shortText(selected.seed_query, 36)} : null}
+ {loading ? 載入中… : null}
+
+
+
+ {WORKSPACE_TABS.map((tab) => (
+
+ ))}
+
+
+ {workspaceTab === "settings" && (
+
+
+
+ setSelected({ ...selected, topic_name: e.target.value })} />
+
+
+ setSelected({ ...selected, seed_query: e.target.value })} />
+
+
+
+
+
+
+
+
+
+
+ 關聯品牌:{currentBrand?.display_name || selected.brand_id}
+
+
+ 輸入種子關鍵字後點「AI 產生研究地圖 + 知識圖譜」,會產出結構化的受眾、問題、支柱與三層知識圖譜。
+
+
+ )}
+
+ {workspaceTab === "map" && (
+
+ {!selected?.research_map || !selected.research_map.audience_summary ? (
+
+
尚未產生。請到「主題設定」點「AI 產生研究地圖 + 知識圖譜」。
+
+
+ ) : (
+ <>
+
+ 受眾摘要(TA)
+ {selected.research_map.audience_summary}
+
+
+
+ 內容目標 / 置入時機
+ {selected.research_map.content_goal}
+
+
+ {selected.research_map.questions && selected.research_map.questions.length > 0 && (
+
+ 受眾會問什麼(痛點導向問題)
+ {selected.research_map.questions.map((q, i) => (
+ {q}
+ ))}
+
+ )}
+
+ {selected.research_map.pillars && selected.research_map.pillars.length > 0 && (
+
+ 內容支柱方向
+
+ {selected.research_map.pillars.map((p, i) => (
+ {p}
+ ))}
+
+
+ )}
+
+ {selected.research_map.exclusions && selected.research_map.exclusions.length > 0 && (
+
+ 排除項目
+
+ {selected.research_map.exclusions.map((e, i) => (
+ {e}
+ ))}
+
+
+ )}
+
+ {selected.research_map.patrol_keywords && selected.research_map.patrol_keywords.length > 0 && (
+
+ 建議搜尋關鍵字
+
+ {selected.research_map.patrol_keywords.map((k, i) => (
+ {k}
+ ))}
+
+
+ )}
+
+
+
+
+
+ >
+ )}
+
+ )}
+
+ {workspaceTab === "graph" && (
+
+
+
+
+ {graph && graph.nodes?.length > 0 && (
+ <>
+
+
+
+ >
+ )}
+
+
+ {graph && graph.nodes && graph.nodes.length > 0 ? (
+ <>
+
+ 種子:{selected?.seed_query || ""}
+ {graph.nodes.length} 個節點
+ {graph.brave_sources && graph.brave_sources.length > 0 && (
+ {graph.brave_sources.length} 個參考連結
+ )}
+ = 8 ? "success" : "warning"}>
+ 痛點候選 {(graph as any).pain_tag_count || 0}
+
+ 已勾選 {graph.nodes.filter((n) => n.selected_for_scan).length}
+
+
+
+ {[0, 1, 2].map((l) => {
+ const layerNodes = graph.nodes.filter((n) => n.layer === l);
+ const label = l === 0 ? "核心層 (L0)" : l === 1 ? "延伸層 (L1)" : "周邊層 (L2)";
+ const isActive = activeGraphLayer === l;
+ return (
+
+ );
+ })}
+
+
+
+
+ {activeGraphLayer === 0 ? "核心層 (L0)" : activeGraphLayer === 1 ? "延伸層 (L1)" : "周邊層 (L2)"}
+
+
+ 延伸知識由內而外擴展(核心 → 直接相關 → 周邊情境)。勾選痛點節點後點「儲存勾選」供海巡使用。
+
+
+ {graph.nodes.filter((n) => n.layer === activeGraphLayer).length === 0 ? (
+
這一層目前沒有節點,請切換上方 L0 / L1 / L2 分頁。
+ ) : null}
+ {graph.nodes
+ .filter((n) => n.layer === activeGraphLayer)
+ .sort((a, b) => b.product_fit_score - a.product_fit_score)
+ .map((node) => {
+ const evidence = (node.evidence || []).filter((e) => e.url);
+ return (
+
+
+ void toggleNodeScan(node)}
+ />
+ {node.label}
+ {node.node_kind || node.type}
+ = 70 ? "success" : node.product_fit_score >= 40 ? "warning" : "neutral"}>
+ 契合 {node.product_fit_score}
+
+
+
+ {node.relation && (
+
+ 脈絡: {node.relation}
+
+ )}
+ {node.placement_value && (
+
+ 置入價值: {node.placement_value}
+
+ )}
+
+ {((node.relevance_tags && node.relevance_tags.length) || (node.recency_tags && node.recency_tags.length)) && (
+
+
搜尋建議 / 標籤
+
+ {(node.relevance_tags || []).slice(0, 4).map((q: string, i: number) => (
+ {q}
+ ))}
+ {(node.recency_tags || []).slice(0, 3).map((q: string, i: number) => (
+ {q}
+ ))}
+
+
+ )}
+
+ {evidence.length > 0 && (
+
+ )}
+
+ );
+ })}
+
+
+ >
+ ) : (
+
尚未產生知識圖譜。請先產生研究地圖,然後點「擴展知識圖譜」產生三層延伸知識。
+ )}
+
+ )}
+
+ {workspaceTab === "patrol" && (
+
+
+ 出發前確認
+
+ {patrolChecks.map((check) => (
+ -
+ {check.ok ? "✓" : "!"}
+
+
{check.text}
+ {check.hint ?
{check.hint}
: null}
+
+
+ ))}
+
+
+
+
+ 將送出的搜尋關鍵字(依相關性精選)
+
+ 研究地圖與圖譜只是候選來源。實際搜尋會依管道自動裁切:Threads API 用短核心詞(痛點+品類);Search API 近期軌用短詞+請問,相關軌用稍長的求助句以提高精準度。
+
+ {patrolPlan.finalItems.length > 0 ? (
+
+ {patrolPlan.finalItems.map((item, idx) => (
+
+ {idx + 1}
+ {item.keyword}
+ {patrolOriginLabel(item.origin)}
+
+ ))}
+
+ ) : (
+ 完成上方確認項目後,關鍵字會出現在這裡。
+ )}
+
+
+ {!patrolPlan.isManual && patrolPlan.groups.some((g) => g.items.length > 0) ? (
+
+ 追溯:候選來源(不等於最終送出順序)
+
+ {patrolPlan.groups.map((group) =>
+ group.items.length > 0 ? (
+
+
{group.title}
+
+ {group.items.map((item, idx) => (
+
+ {item.keyword}
+
+ ))}
+
+
+ ) : null
+ )}
+
+
+ ) : null}
+
+
+ setDiscoveryKeywords(e.target.value)}
+ placeholder="空白表示使用自動精選"
+ />
+
+
+
+
+ {devModeEnabled ? (
+
+ ) : null}
+ {patrolPlan.selectedNodeCount === 0 ? (
+
+ ) : null}
+ {!selected?.research_map?.audience_summary ? (
+
+ ) : null}
+
+ {devModeEnabled && !browserConnected ? (
+
+ 測試海巡需先在「設定」開啟開發模式,並到「Threads 帳號」同步 Chrome Extension Session。
+
+ ) : null}
+
+ )}
+
+ {workspaceTab === "results" && (
+
+
+ 在此閱讀、判斷、回覆
+
+ 完整討論與留言都留在這裡。只保留有明確需求/痛點、你的產品能解決、且品類不錯配的討論;海巡會先搜近 7 天,某關鍵字結果不足時自動往近 14 天、近 30 天擴搜。
+ {topicProduct
+ ? ` 主題預設產品:${topicProduct.label}(每則貼文會依內容自動推薦最適合的 SKU)`
+ : " 請先在品牌綁定產品與 match tags。"}
+
+
+
+
+
+
+ {resultsRecentOnly || resultsMinFit > 0 ? (
+
+ 目前套用篩選,較低契合或較舊的候選可能暫時看不到。將「產品契合」設為「全部」可顯示海巡存下的所有結果。
+
+ ) : null}
+
+
+
+
+
+
+
+
+ {pendingDraftJobIds.length > 0 ? (
+ 草稿任務進行中:{pendingDraftJobIds.length}(可離開此頁)
+ ) : null}
+
+
+
+
+ {posts.length === 0 ? (
+
+ {resultsRecentOnly || resultsMinFit > 0
+ ? "篩選後沒有符合的候選。試著關閉「只顯示近 7 天」或將產品契合改為「全部」。"
+ : patrolJobWatchId
+ ? "海巡進行中,完成後會自動載入結果;也可稍後按「重新載入」。"
+ : "目前沒有候選討論。請到「海巡」啟動搜尋。"}
+
+ ) : (
+
+ {posts.map((post) => {
+ const node = graphNodeForPost(graph, post);
+ const postProduct = resolveProductForPost({
+ brand: currentBrand,
+ topic: selected,
+ searchTag: post.search_tag,
+ postText: post.text,
+ });
+ const opportunity = placementOpportunity(
+ post,
+ node,
+ postProduct?.label || "",
+ postProduct?.match_tags || []
+ );
+ const drafts = post.latest_draft?.drafts || [];
+ const draftIndex = pickedDraftIndex[post.id] ?? 0;
+ const pickedText = pickedDraftText[post.id] ?? drafts[draftIndex]?.text ?? drafts[0]?.text ?? "";
+ const draftDirty =
+ drafts.length > 0 &&
+ pickedText.trim() !== (drafts[draftIndex]?.text ?? drafts[0]?.text ?? "").trim();
+ const postDraftJobId = draftJobByPostId[post.id];
+ const postDraftJobStatus = postDraftJobId ? draftJobStatusById[postDraftJobId] : "";
+ const postDraftJobActive = postDraftJobStatus ? DRAFT_JOB_ACTIVE.has(postDraftJobStatus) : false;
+ const replyTargetId = resolveReplyTargetId(post);
+ const canPublishViaApi = Boolean(replyTargetId && pickedText.trim());
+ const publishFeedback = publishFeedbackByPostId[post.id];
+ const isSelected = selectedPostIds.includes(post.id);
+ const categoryMismatch = looksCategoryMismatch(post.text, postProduct?.label || "", postProduct?.match_tags || []);
+ const productDiffersFromTopicDefault =
+ Boolean(topicProduct && postProduct && topicProduct.id !== postProduct.id);
+ const isRecent =
+ post.priority === "gold" ||
+ (post.recency_days != null && post.recency_days > 0 && post.recency_days <= 7) ||
+ post.priority === "recent";
+ return (
+
+
+
+
+
{post.text}
+ {post.replies && post.replies.length > 0 && (
+
+
+ 底下留言({post.replies.length})— 在這裡看完再決定怎麼回
+
+ {post.replies.map((reply, idx) => (
+
+
@{reply.author || "匿名"}
+ {reply.like_count != null ?
· {reply.like_count} 讚 : null}
+
{reply.text}
+
+ ))}
+
+ )}
+
+
+
+ 置入建議
+
+
+ 建議產品:{postProduct?.label || "未綁定產品"}
+
+ {node?.label ? 痛點:{node.label} : null}
+ {node?.product_fit_score != null ? (
+ = 70 ? "success" : "warning"}>
+ 節點契合 {node.product_fit_score}
+
+ ) : null}
+
+ {opportunity}
+
+
+ {drafts.length > 0 && (
+
+
+ 回覆草稿(依「{selectedPersona?.display_name || "未選人設"}」語氣,可編輯後以 API 發佈)
+
+ {post.latest_draft?.create_at ? (
+
+ 最新生成:{formatNano(post.latest_draft.create_at)}
+ {post.latest_draft.id ? ` · #${post.latest_draft.id.slice(0, 8)}` : ""}
+
+ ) : null}
+ {post.latest_draft?.reason ? (
+ {post.latest_draft.reason}
+ ) : null}
+ {postProduct?.placement_url ? (
+
+ 置入網址:
+
+ {postProduct.placement_url}
+
+ (AI 會嘗試自然帶入至少一則草稿)
+
+ ) : null}
+
+ {drafts.map((draft, idx) => (
+
+ ))}
+
+
+
+
+
+
發佈預覽(Threads 會保留換行)
+
{pickedText || "(空白)"}
+
+
+ {draftDirty ? (
+
+
+
+ ) : null}
+
+ )}
+
+ {publishingPostId === post.id ? (
+
+ 正在透過 Threads API 發送留言,請稍候…
+
+ ) : null}
+ {publishFeedback ? (
+
+
+ {publishFeedback.kind === "success"
+ ? "發佈成功"
+ : publishFeedback.kind === "error"
+ ? "發佈失敗"
+ : "提示"}
+
+
{publishFeedback.message}
+ {publishFeedback.permalink ? (
+
+ 查看已發佈回覆
+
+ ) : null}
+
+ ) : null}
+
+
+
+ );
+ })}
+
+ )}
+
+ )}
+