VIBN Frontend for Coolify deployment
This commit is contained in:
76
app/api/v0/generate/route.ts
Normal file
76
app/api/v0/generate/route.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { v0 } from 'v0-sdk';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { prompt, style, projectId } = await request.json();
|
||||
|
||||
if (!prompt) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Prompt is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Check for API key
|
||||
const apiKey = process.env.V0_API_KEY;
|
||||
if (!apiKey) {
|
||||
return NextResponse.json(
|
||||
{ error: 'V0_API_KEY not configured' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Create system message based on style
|
||||
const styleInstructions: Record<string, string> = {
|
||||
modern: 'Create a modern, sleek design with clean lines and contemporary aesthetics',
|
||||
minimal: 'Create a minimal, clean design with lots of whitespace and simple elements',
|
||||
colorful: 'Create a vibrant, colorful design with bold colors and energetic feel',
|
||||
dark: 'Create a dark mode design with dark backgrounds and light text',
|
||||
glassmorphism: 'Create a glassmorphism design with frosted glass effects and transparency',
|
||||
};
|
||||
|
||||
const styleInstruction = style && styleInstructions[style]
|
||||
? styleInstructions[style]
|
||||
: 'Create a modern, professional design';
|
||||
|
||||
const systemMessage = `You are an expert React and Tailwind CSS developer. ${styleInstruction}. Use Next.js conventions and best practices. Make it responsive and accessible.`;
|
||||
|
||||
// Create a new chat with v0
|
||||
const chat = await v0.chats.create({
|
||||
message: prompt,
|
||||
system: systemMessage,
|
||||
});
|
||||
|
||||
// Type guard to check if chat has the expected structure
|
||||
if (!('id' in chat) || !('messages' in chat)) {
|
||||
throw new Error('Unexpected response format from v0 API');
|
||||
}
|
||||
|
||||
console.log(`[v0] Chat created: ${chat.id}`);
|
||||
|
||||
// Extract the generated code from the latest message
|
||||
const latestMessage = chat.messages[chat.messages.length - 1];
|
||||
const code = latestMessage?.content || '';
|
||||
|
||||
// Return the chat details
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
chatId: chat.id,
|
||||
webUrl: chat.webUrl,
|
||||
code,
|
||||
message: latestMessage,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[v0] Error generating design:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to generate design',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
101
app/api/v0/import-chat/route.ts
Normal file
101
app/api/v0/import-chat/route.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { v0 } from 'v0-sdk';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { chatId, chatUrl } = await request.json();
|
||||
|
||||
if (!chatId && !chatUrl) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Either chatId or chatUrl is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Check for API key
|
||||
const apiKey = process.env.V0_API_KEY;
|
||||
if (!apiKey) {
|
||||
return NextResponse.json(
|
||||
{ error: 'V0_API_KEY not configured' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Extract chat ID from URL if provided
|
||||
let extractedChatId = chatId;
|
||||
if (chatUrl && !chatId) {
|
||||
// v0.dev URLs look like: https://v0.dev/chat/abc123xyz
|
||||
const match = chatUrl.match(/\/chat\/([^/?]+)/);
|
||||
if (match) {
|
||||
extractedChatId = match[1];
|
||||
} else {
|
||||
return NextResponse.json(
|
||||
{ error: 'Invalid v0 chat URL format' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[v0] Attempting to import chat: ${extractedChatId}`);
|
||||
|
||||
// The v0 SDK doesn't support retrieving individual chats by ID
|
||||
// We'll store a reference to the chat URL for the user to access it
|
||||
const fullChatUrl = chatUrl || `https://v0.dev/chat/${extractedChatId}`;
|
||||
|
||||
console.log(`[v0] Importing chat reference: ${extractedChatId}`);
|
||||
|
||||
const chatInfo = {
|
||||
id: extractedChatId,
|
||||
webUrl: fullChatUrl,
|
||||
message: 'Chat link saved. You can access it via the web URL.',
|
||||
note: 'The v0 API does not currently support retrieving chat history via API. Use the web URL to view and continue the conversation.'
|
||||
};
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
chat: chatInfo,
|
||||
message: 'Chat reference saved successfully'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[v0] Error importing chat:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to import chat',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Also support GET for testing
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const chatId = searchParams.get('chatId');
|
||||
const chatUrl = searchParams.get('chatUrl');
|
||||
|
||||
if (!chatId && !chatUrl) {
|
||||
return NextResponse.json({
|
||||
message: 'Import a v0 chat',
|
||||
usage: 'POST /api/v0/import-chat with { "chatId": "abc123" } or { "chatUrl": "https://v0.dev/chat/abc123" }',
|
||||
example: {
|
||||
method: 'POST',
|
||||
body: {
|
||||
chatUrl: 'https://v0.dev/chat/your-chat-id'
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Forward to POST handler
|
||||
const body = JSON.stringify({ chatId, chatUrl });
|
||||
const req = new Request(request.url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body,
|
||||
});
|
||||
|
||||
return POST(req);
|
||||
}
|
||||
|
||||
41
app/api/v0/iterate/route.ts
Normal file
41
app/api/v0/iterate/route.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { v0 } from 'v0-sdk';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { chatId, message, projectId } = await request.json();
|
||||
|
||||
if (!chatId || !message) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Missing required fields: chatId and message' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`[API] Iterate request for chat ${chatId}`);
|
||||
|
||||
// The v0 SDK doesn't support sending follow-up messages via API
|
||||
// Users need to continue the conversation on v0.dev
|
||||
const webUrl = `https://v0.dev/chat/${chatId}`;
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
chatId: chatId,
|
||||
webUrl: webUrl,
|
||||
message: 'To continue this conversation, please visit the chat on v0.dev',
|
||||
note: 'The v0 API does not currently support sending follow-up messages. Use the web interface to iterate on your design.',
|
||||
yourMessage: message,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[API] Error processing iteration request:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: error instanceof Error ? error.message : 'Failed to process request',
|
||||
details: error instanceof Error ? error.stack : undefined,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
68
app/api/v0/list-chats/route.ts
Normal file
68
app/api/v0/list-chats/route.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { v0 } from 'v0-sdk';
|
||||
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
// Check for API key
|
||||
const apiKey = process.env.V0_API_KEY;
|
||||
if (!apiKey) {
|
||||
return NextResponse.json(
|
||||
{ error: 'V0_API_KEY not configured' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('[v0] Attempting to list chats...');
|
||||
|
||||
// Try to list chats - this may or may not be supported
|
||||
// The v0 SDK documentation shows chats.create() but we need to check if list() exists
|
||||
try {
|
||||
// @ts-ignore - Checking if this method exists
|
||||
const chats = await v0.chats.list();
|
||||
console.log('[v0] Chats retrieved:', chats);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
chats,
|
||||
count: chats?.length || 0,
|
||||
});
|
||||
} catch (listError) {
|
||||
console.error('[v0] List method error:', listError);
|
||||
|
||||
// Try alternative: Get account info or projects
|
||||
try {
|
||||
// @ts-ignore - Checking if this method exists
|
||||
const projects = await v0.projects?.list();
|
||||
console.log('[v0] Projects retrieved:', projects);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
projects,
|
||||
count: projects?.length || 0,
|
||||
note: 'Retrieved projects instead of chats'
|
||||
});
|
||||
} catch (projectError) {
|
||||
console.error('[v0] Projects error:', projectError);
|
||||
|
||||
return NextResponse.json({
|
||||
error: 'Unable to list chats or projects',
|
||||
details: 'The v0 SDK may not support listing existing chats via API',
|
||||
suggestion: 'You may need to manually provide chat IDs to import existing designs',
|
||||
sdkError: listError instanceof Error ? listError.message : 'Unknown error'
|
||||
}, { status: 400 });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[v0] Error:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to access v0 API',
|
||||
details: error instanceof Error ? error.message : 'Unknown error',
|
||||
tip: 'The v0 SDK primarily supports creating new chats. To import existing designs, you may need to provide specific chat IDs or URLs.'
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user