Smart Board Analysis
Relevant source files
The following files were used as context for generating this wiki page:
The Smart Board is a core feature of the Nota application, designed to transform a raw YouTube video transcript into multiple, high-fidelity content structures. It acts as a central dashboard for viewing AI-generated content, including key takeaways, social media posts, and blog outlines. This system is powered by the Google Gemini API and is designed to provide "Random Access Intelligence" by turning long-form video content into an actionable workspace.
The Smart Board is composed of a primary UI component (SmartBoard.tsx), a state management hook (useContentGenerator.ts) that orchestrates AI calls, and a service layer (geminiService.ts) that communicates with the Gemini API. It also displays user-generated "Surgical AI Notes" which are created by highlighting text in the transcript.
Sources: README.md:16-22, components/SmartBoard.tsx, App.tsx:173-183
System Architecture
The Smart Board's functionality is driven by a clear separation of concerns between the main application component, a custom React hook for state management, the UI presentation component, and the AI service layer.
The diagram below illustrates the high-level interaction between these key modules.
This diagram shows that App.tsx orchestrates the process. It uses useTranscript to get the video transcript, then triggers the useContentGenerator hook. This hook calls the geminiService to generate content, which is then passed to the SmartBoard component for display. The generated content is also cached in localStorage.
Sources: App.tsx:31-48, hooks/useContentGenerator.ts:80-87
Data Flow and Content Generation
Content generation is automatically triggered when a new video transcript is successfully loaded. The useContentGenerator hook is responsible for this entire workflow.
Generation Sequence
The following sequence diagram details the steps from loading a video to displaying the generated content on the Smart Board.
This flow highlights the parallel execution of AI generation tasks using Promise.allSettled for efficiency and the caching mechanism to avoid redundant API calls for the same video.
Sources: hooks/useContentGenerator.ts:80-145, App.tsx:42-48
Core Components
SmartBoard.tsx
This is the primary React component responsible for rendering the entire Smart Board interface. It features a tabbed navigation system to switch between different types of generated content and user notes.
Key Responsibilities:
- Displays a tab for each content type: "Takeaways", "Thread", "LinkedIn", "Blog", and "Notes".
- Renders loading indicators for each content type based on the
progressprop. - Displays the generated content for the active tab.
- Provides UI for copying content to the clipboard.
- Renders a list of
NoteCardcomponents for the "Notes" tab.
Component Props:
| Prop | Type | Description |
|---|---|---|
content | ContentOutput | null | The object containing all AI-generated content. |
notes | Note[] | An array of user-generated notes. |
isGenerating | boolean | A flag indicating if any generation is in progress. |
progress | GenerationProgress | An object tracking the status ('loading', 'done', etc.) of each content type. |
onDeleteNote | (id: string) => void | Callback function to delete a note. |
onJumpToTime | (time: number) => void | Callback function to seek the video to a specific timestamp. |
processingStatus | ProcessingStatus | Status of the "Surgical AI Notes" generation. |
currentDraft | string | The raw text currently being summarized for a note. |
Sources: components/SmartBoard.tsx:11-26, 47-60
useContentGenerator.ts
This custom hook encapsulates all logic related to fetching, managing, and caching the AI-generated content for the Smart Board.
Key Responsibilities:
- Manages the
contentstate object and theprogressof generation tasks. - On initialization with a
videoId, it attempts to load cached content fromlocalStorage. - The
generateAllfunction orchestrates parallel API calls to thegeminiServicefor all content types. - Saves newly generated content to
localStorageto persist it for the currentvideoId. - Provides a
clearContentfunction to reset the state and clear the cache.
Hook Return Value:
| Name | Type | Description |
|---|---|---|
content | ContentOutput | null | The generated content object. |
isGenerating | boolean | True if any generation task is in the 'loading' state. |
progress | GenerationProgress | The status of each generation task. |
generateAll | (transcript: string) => Promise<void> | Function to trigger the generation of all content. |
clearContent | () => void | Function to clear content and localStorage. |
hasContent | boolean | True if the content object is not null. |
Sources: hooks/useContentGenerator.ts:19-30, 80-87
AI Content Generation
All AI functionality is handled by geminiService.ts, which acts as a wrapper around the @google/genai SDK. It defines specific functions for each content generation task, each with a tailored system instruction (prompt).
Generation Functions and Prompts
The service exposes several functions, each designed to produce a specific content format. The core logic is abstracted into a generic generateAIContent function that takes a system instruction and handles the API call and JSON parsing.
| Function | Output Type | System Instruction Summary |
|---|---|---|
generateKeyTakeaways | KeyTakeaway[] | "You are a learning assistant. Extract 5-7 key takeaways... Output EXACTLY in this JSON format..." |
generateTwitterThread | string[] | "You are a viral content creator... convert a video transcript into a high-engagement Twitter thread (7-10 tweets)..." |
generateLinkedInPost | LinkedInPost | "You are a professional LinkedIn thought leader... Output EXACTLY in this JSON format..." |
generateBlogOutline | BlogOutline | "You are an SEO content strategist... Convert this video transcript into a blog post outline. Output EXACTLY in this JSON format..." |
The prompts are highly specific, instructing the AI to return data in a precise JSON format to ensure reliable parsing.
Sources: services/geminiService.ts:168-176, 180-186, 190-196, 200-207
Generic AI Content Generation Flow
The generateAIContent function standardizes the process of calling the Gemini API and parsing the response.
// services/geminiService.ts:101-134
async function generateAIContent<T>(
apiKey: string,
transcript: string,
systemInstruction: string,
fallbackValue: T,
temperature: number = 0.5
): Promise<T> {
const ai = new GoogleGenAI({ apiKey });
try {
const response = await ai.models.generateContent({
model: 'gemini-2.0-flash',
contents: transcript.slice(0, AI_LIMITS.TRANSCRIPT_SLICE),
config: { systemInstruction, temperature }
});
const text = response.text || "";
const cleaned = text.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
return JSON.parse(cleaned);
} catch (e) {
console.error("AI Generation Failed:", e);
return fallbackValue;
}
}
This function demonstrates key practices:
- Slicing the transcript to respect input limits.
- Using a
systemInstructionto guide the model's behavior. - Cleaning potential markdown code fences from the AI's response.
- Parsing the cleaned text as JSON.
- Returning a
fallbackValueon failure to prevent application crashes.
Sources: services/geminiService.ts:101-134
Data Models
The structure of the AI-generated content is strictly defined in types.ts. These types ensure type safety and guide the development of both the AI prompts and the frontend components that consume the data.
Content Structure Diagram
The following diagram shows the relationship between the main ContentOutput type and its nested structures.
Data Type Definitions
ContentOutput
This is the main container for all generated content, stored in localStorage.
| Field | Type | Description |
|---|---|---|
twitterThread | string[] | null | An array of strings, where each string is a tweet. |
linkedInPost | LinkedInPost | null | An object representing a LinkedIn post. |
blogOutline | BlogOutline | null | An object representing a blog post outline. |
keyTakeaways | KeyTakeaway[] | null | An array of key takeaway objects. |
generatedAt | number | Timestamp of when the content was generated. |
Sources: types.ts:49-56
LinkedInPost
| Field | Type | Description |
|---|---|---|
hook | string | An attention-grabbing first line. |
body | string | The main content of the post. |
cta | string | A call to action to encourage engagement. |
hashtags | string[] | An array of relevant hashtags. |
Sources: types.ts:28-33
BlogOutline
| Field | Type | Description |
|---|---|---|
title | string | An SEO-optimized title for the blog post. |
sections | BlogSection[] | An array of section objects for the outline. |
seoKeywords | string[] | An array of relevant SEO keywords. |
Sources: types.ts:40-44
KeyTakeaway
| Field | Type | Description |
|---|---|---|
emoji | string | A relevant emoji for the takeaway. |
text | string | The concise, actionable takeaway text. |
Sources: types.ts:46-48
Conclusion
The Smart Board Analysis feature is a well-architected system that effectively decouples UI, state management, and external services. By leveraging a dedicated React hook (useContentGenerator) and a robust service layer (geminiService) with precise AI prompting, it can reliably transform unstructured transcript data into a variety of valuable, structured content formats. The use of parallel processing for generation and local storage for caching ensures an efficient and responsive user experience.