No content found.
Start a new search or create your first piece of content!
diff --git a/components/Layout/Dashboard/Generate/ApiSenderDialog.tsx b/components/Layout/Dashboard/Generate/ApiSenderDialog.tsx
index 4224f7c..7a6128d 100644
--- a/components/Layout/Dashboard/Generate/ApiSenderDialog.tsx
+++ b/components/Layout/Dashboard/Generate/ApiSenderDialog.tsx
@@ -24,6 +24,7 @@ import { useContent } from '@/context/GenerationContext';
import { cn } from '@/lib/utils';
import { Input } from '@/components/ui/input';
import { motion } from 'framer-motion';
+import { makeRequest } from '@/lib/actions/content.actions';
export const ApiSenderDialog = ({ isOpen, onClose }) => {
// Mock hook usage
@@ -106,20 +107,13 @@ export const ApiSenderDialog = ({ isOpen, onClose }) => {
setErrorDetails('');
setApiResult(null);
- // --- Start Mock API Call (Replace this section with actual fetch in a real environment) ---
try {
- // Implement exponential backoff for resilience (optional but good practice)
const maxRetries = 3;
let delay = 1000;
for (let i = 0; i < maxRetries; i++) {
try {
- // Simulate successful response
- const mockResponse = {
- id: 'post-' + Math.floor(Math.random() * 10000),
- status: 'published',
- url: 'https://preview.yourcms.com/article/' + Math.floor(Math.random() * 10000),
- };
+ const mockResponse = await makeRequest(apiEndpoint, customBody);
setApiResult(mockResponse);
setStatus('success');
diff --git a/components/Layout/Dashboard/Generate/ContentRenderer.tsx b/components/Layout/Dashboard/Generate/ContentRenderer.tsx
index 8414713..e003dec 100644
--- a/components/Layout/Dashboard/Generate/ContentRenderer.tsx
+++ b/components/Layout/Dashboard/Generate/ContentRenderer.tsx
@@ -10,6 +10,7 @@ import '@mdxeditor/editor/style.css';
import rehypeRaw from 'rehype-raw';
import { useGlobalState } from '@/context/GlobalStateContext';
import { useContent } from '@/context/GenerationContext';
+import { PromptSelector } from '@/components/Layout/Dashboard/Generate/PromptSelector';
interface ContentRendererProps {
isLoading: boolean;
@@ -52,7 +53,7 @@ export const Content: React.FC = ({ isLoading }: { isLoadi
>
{isLoading ? (
- ) : (
+ ) : !generatedContent && !isLoading ? () : (
// ARTICLE CONTAINER: This is where we control the content's width.
// - max-w-4xl mx-auto: Limits content to a readable width (e.g., 56rem) and centers it.
// - flex-col: Ensures Markdown content stacks vertically.
diff --git a/components/Layout/Dashboard/Generate/PromptSelector.tsx b/components/Layout/Dashboard/Generate/PromptSelector.tsx
new file mode 100644
index 0000000..bdf72d3
--- /dev/null
+++ b/components/Layout/Dashboard/Generate/PromptSelector.tsx
@@ -0,0 +1,161 @@
+'use client'
+
+import React, { useState } from 'react';
+import {
+ Feather, // Placeholder icon for writing
+ FileText,
+ Rocket,
+ Search,
+ Zap,
+ CheckCircle,
+ TrendingUp,
+} from 'lucide-react';
+import { cn } from '@/lib/utils';
+import { motion } from 'framer-motion';
+import { useContent } from '@/context/GenerationContext';
+
+// --- Prompt Data Structure ---
+interface Prompt {
+ id: string;
+ title: string;
+ icon: React.ElementType;
+ summary: string;
+ fullPrompt: string;
+}
+
+// --- List of Well-Written Prompts ---
+const professionalPrompts: Prompt[] = [
+ {
+ id: 'p-1',
+ title: 'Executive Summary Generator',
+ icon: FileText,
+ summary: 'Analyze a 500-word document and extract the three most critical takeaways, summarizing them into a professional executive overview, suitable for C-level review.',
+ fullPrompt: 'Analyze the provided text. Identify the three most critical business insights, risks, or opportunities. Summarize these points into a single, concise executive summary paragraph, maintaining a formal and objective tone.',
+ },
+ {
+ id: 'p-2',
+ title: 'SEO-Optimized Blog Post',
+ icon: TrendingUp,
+ summary: 'Generate a 1000-word blog post on "The Future of Quantum Computing," incorporating a required set of five target keywords naturally throughout the text.',
+ fullPrompt: 'Draft a 1000-word SEO-optimized blog post titled "The Future of Quantum Computing." The post must include the following keywords: [quantum entanglement], [superposition], [qubit], [d-wave], and [quantum supremacy]. Structure the post with a compelling introduction, three detailed body sections, and a conclusion with a clear call to action.',
+ },
+ {
+ id: 'p-3',
+ title: 'Competitive Analysis Report',
+ icon: Search,
+ summary: 'Conduct a high-level competitive analysis of three specified companies, detailing their market position, primary product, and unique selling proposition (USP).',
+ fullPrompt: 'Perform a high-level competitive analysis comparing Company A, Company B, and Company C. For each company, detail their current market share (if known), their flagship product, their core technology advantage, and a concise summary of their Unique Selling Proposition (USP). Present the findings in a clear, comparative table format.',
+ },
+ {
+ id: 'p-4',
+ title: 'Viral Social Media Campaign',
+ icon: Rocket,
+ summary: 'Design a three-part social media campaign (Twitter thread, LinkedIn post, Instagram caption) to promote a new SaaS feature launch.',
+ fullPrompt: 'Design a high-impact, three-part social media campaign to promote the launch of a new SaaS feature: "Real-time AI Document Collaboration." Create a compelling, detailed Twitter thread (max 7 tweets), a professional LinkedIn post focused on business value, and a short, engaging Instagram caption with relevant hashtags.',
+ },
+];
+
+
+export const PromptSelector = () => {
+ // State to track the ID of the currently selected prompt
+ const [selectedPromptId, setSelectedPromptId] = useState(null);
+
+ const { setPrompt } = useContent();
+
+ // Derive the full details of the selected prompt
+ const selectedPrompt = professionalPrompts.find(p => p.id === selectedPromptId);
+
+ const handleSelect = (id: string, prompt = '') => {
+ setSelectedPromptId(id === selectedPromptId ? null : id);
+ setPrompt(prompt);
+ };
+
+ return (
+
+
+
+ Prompt Templates Library
+
+
+ Select a template to instantly load a professionally written prompt into the editor, or use it as inspiration.
+
+
+ {/* Prompt Grid Container (Responsive Layout) */}
+
+ {professionalPrompts.map((prompt) => {
+ const isSelected = prompt.id === selectedPromptId;
+ const IconComponent = prompt.icon;
+
+ return (
+
handleSelect(prompt.id, prompt.fullPrompt)}
+ className={cn(
+ 'group p-4 rounded-xl border-2 transition-300 cursor-pointer shadow-sm',
+ 'flex flex-col justify-between min-h-[180px]',
+ // Default state
+ 'bg-white border-neutral-200 hover:border-black/50 hover:shadow-md',
+ // Selected state
+ isSelected
+ ? 'border-black bg-black text-white shadow-xl ring-2 ring-offset-2 ring-black/50'
+ : 'text-neutral-900',
+ )}
+ >
+
+
+
+
+
+ {prompt.title}
+
+
+
+
+
+ {isSelected && (
+
+ Selected
+
+ )}
+
+ );
+ })}
+
+
+ {/*/!* Selected Prompt Display (for demonstration) *!/*/}
+ {/*{selectedPrompt && (*/}
+ {/*
*/}
+ {/* */}
+ {/* */}
+ {/* Active Prompt Text*/}
+ {/*
*/}
+ {/* */}
+ {/* {selectedPrompt.fullPrompt}*/}
+ {/*
*/}
+ {/* */}
+ {/* *This text is now ready to be loaded into your main input field.**/}
+ {/*
*/}
+ {/* */}
+ {/*)}*/}
+
+ );
+};
\ No newline at end of file
diff --git a/components/Layout/Dashboard/Generate/content/Renderer.tsx b/components/Layout/Dashboard/Generate/content/Renderer.tsx
index 6688e1a..03f2f01 100644
--- a/components/Layout/Dashboard/Generate/content/Renderer.tsx
+++ b/components/Layout/Dashboard/Generate/content/Renderer.tsx
@@ -11,6 +11,7 @@ import { MarkdownViewer } from '@/components/Layout/Dashboard/Generate/content/M
import { Source } from '../RightSidebarPanel';
import EditorLoader from '@/components/Layout/Dashboard/Generate/Editor/EditorLoader';
import { FileText, PenLine, Link as LinkIcon, Code } from 'lucide-react';
+import { PromptSelector } from '@/components/Layout/Dashboard/Generate/PromptSelector';
const Editor = dynamic(() => import('../Editor/Editor'), {
// Make sure we turn SSR off
@@ -54,6 +55,12 @@ export default function Renderer() {
>
+
+
+