v3.0.1: Complete frontend integration with FastAPI backend
Some checks are pending
CI / build (18.x) (push) Waiting to run
CI / build (20.x) (push) Waiting to run

- Update Gallery.tsx to use FastAPI (5 API calls)
- Update PromptHero.tsx to use FastAPI (3 API calls)
- Update PromptLibrary.tsx to use FastAPI (4 API calls)
- Update UploadHistory.tsx to use FastAPI (1 API call)
- Add API_BASE constant to all components
This commit is contained in:
Khoa.vo 2026-01-13 07:52:58 +07:00
parent 0ef7e5475c
commit 2d301d6594
4 changed files with 25 additions and 13 deletions

View file

@ -8,6 +8,9 @@ import { Download, Maximize2, Sparkles, Trash2, X, ChevronLeft, ChevronRight, Co
import { VideoPromptModal } from './VideoPromptModal'; import { VideoPromptModal } from './VideoPromptModal';
import { EditPromptModal } from './EditPromptModal'; import { EditPromptModal } from './EditPromptModal';
// FastAPI backend URL
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
// Helper function to get proper image src (handles URLs vs base64) // Helper function to get proper image src (handles URLs vs base64)
const getImageSrc = (data: string): string => { const getImageSrc = (data: string): string => {
if (!data) return ''; if (!data) return '';
@ -111,7 +114,7 @@ export function Gallery() {
} }
} catch (e) { console.error("Cookie merge failed", e); } } catch (e) { console.error("Cookie merge failed", e); }
const res = await fetch('/api/meta/video', { const res = await fetch(`${API_BASE}/meta/video`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -168,7 +171,7 @@ export function Gallery() {
setIsGeneratingWhiskVideo(true); setIsGeneratingWhiskVideo(true);
try { try {
const res = await fetch('/api/video/generate', { const res = await fetch(`${API_BASE}/video/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -240,7 +243,7 @@ export function Gallery() {
} }
} catch (e) { console.error("Cookie merge failed", e); } } catch (e) { console.error("Cookie merge failed", e); }
const res = await fetch('/api/meta/generate', { const res = await fetch(`${API_BASE}/meta/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -289,7 +292,7 @@ export function Gallery() {
} }
// First upload the current image as a reference // First upload the current image as a reference
const uploadRes = await fetch('/api/references/upload', { const uploadRes = await fetch(`${API_BASE}/references/upload`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -312,7 +315,7 @@ export function Gallery() {
if (options.keepStyle) refs.style = [uploadData.id]; if (options.keepStyle) refs.style = [uploadData.id];
// Generate new image with references // Generate new image with references
const res = await fetch('/api/generate', { const res = await fetch(`${API_BASE}/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({

View file

@ -5,6 +5,9 @@ import { useStore, ReferenceCategory } from "@/lib/store";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { Sparkles, Maximize2, X, Hash, AlertTriangle, Upload, Brain, Settings, Settings2 } from "lucide-react"; import { Sparkles, Maximize2, X, Hash, AlertTriangle, Upload, Brain, Settings, Settings2 } from "lucide-react";
// FastAPI backend URL
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
const IMAGE_COUNTS = [1, 2, 4]; const IMAGE_COUNTS = [1, 2, 4];
export function PromptHero() { export function PromptHero() {
@ -126,7 +129,7 @@ export function PromptHero() {
const subjectRef = references.subject?.[0]; const subjectRef = references.subject?.[0];
const imageUrl = subjectRef ? subjectRef.thumbnail : undefined; // Use full data URI from thumbnail property const imageUrl = subjectRef ? subjectRef.thumbnail : undefined; // Use full data URI from thumbnail property
res = await fetch('/api/meta/generate', { res = await fetch(`${API_BASE}/meta/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -145,7 +148,7 @@ export function PromptHero() {
style: references.style?.map(r => r.id) || [], style: references.style?.map(r => r.id) || [],
}; };
res = await fetch('/api/generate', { res = await fetch(`${API_BASE}/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -317,7 +320,7 @@ export function PromptHero() {
// If Whisk, upload to backend to get ID // If Whisk, upload to backend to get ID
if (!settings.provider || settings.provider === 'whisk') { if (!settings.provider || settings.provider === 'whisk') {
try { try {
const res = await fetch('/api/references/upload', { const res = await fetch(`${API_BASE}/references/upload`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({

View file

@ -7,6 +7,9 @@ import { cn } from '@/lib/utils';
import { Prompt, PromptCache } from '@/lib/types'; import { Prompt, PromptCache } from '@/lib/types';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
// FastAPI backend URL
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => void }) { export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => void }) {
const { setPrompt, settings } = useStore(); const { setPrompt, settings } = useStore();
const [prompts, setPrompts] = useState<Prompt[]>([]); const [prompts, setPrompts] = useState<Prompt[]>([]);
@ -24,7 +27,7 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
setLoading(true); setLoading(true);
setError(null); setError(null);
try { try {
const res = await fetch('/api/prompts'); const res = await fetch(`${API_BASE}/prompts`);
if (res.ok) { if (res.ok) {
const data: PromptCache = await res.json(); const data: PromptCache = await res.json();
setPrompts(data.prompts); setPrompts(data.prompts);
@ -43,7 +46,7 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
setLoading(true); setLoading(true);
setError(null); setError(null);
try { try {
const syncRes = await fetch('/api/prompts/sync', { method: 'POST' }); const syncRes = await fetch(`${API_BASE}/prompts/sync`, { method: 'POST' });
if (!syncRes.ok) throw new Error('Sync failed'); if (!syncRes.ok) throw new Error('Sync failed');
await fetchPrompts(); await fetchPrompts();
} catch (error) { } catch (error) {
@ -70,7 +73,7 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
try { try {
console.log(`Requesting preview for: ${prompt.title}`); console.log(`Requesting preview for: ${prompt.title}`);
const res = await fetch('/api/prompts/generate', { const res = await fetch(`${API_BASE}/prompts/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@ -118,7 +121,7 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
// Track usage // Track usage
try { try {
await fetch('/api/prompts/use', { await fetch(`${API_BASE}/prompts/use`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: p.id }) body: JSON.stringify({ id: p.id })

View file

@ -5,6 +5,9 @@ import { useStore, ReferenceCategory } from '@/lib/store';
import { Clock, Upload, Trash2, CheckCircle, X, Film, Check } from 'lucide-react'; import { Clock, Upload, Trash2, CheckCircle, X, Film, Check } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
// FastAPI backend URL
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
export function UploadHistory() { export function UploadHistory() {
const { const {
history, setHistory, history, setHistory,
@ -115,7 +118,7 @@ export function UploadHistory() {
// Optimistic UI update could happen here // Optimistic UI update could happen here
const res = await fetch('/api/references/upload', { const res = await fetch(`${API_BASE}/references/upload`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({