Add loading state and style constants, enhance API key modal with delete

This commit is contained in:
Riccardo Giorato
2025-12-26 12:15:01 +01:00
parent 14b247ffaa
commit 66b252fb2e
17 changed files with 379 additions and 198 deletions
+7 -9
View File
@@ -1,18 +1,12 @@
"use client"
import { useState, useRef, useEffect } from "react"
import { useState, useRef, useEffect, useMemo } from "react"
import { Upload, X, Loader2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { useToast } from "@/hooks/use-toast"
import { validateFileForUpload, generateFilePreview } from "@/lib/file-utils"
const COMIC_STYLES = [
{ id: "american-modern", name: "American Modern" },
{ id: "manga", name: "Manga" },
{ id: "noir", name: "Noir" },
{ id: "vintage", name: "Vintage" },
]
import { COMIC_STYLES } from "@/lib/constants"
interface GeneratePageModalProps {
isOpen: boolean
@@ -51,7 +45,11 @@ export function GeneratePageModal({
const fileInputRef = useRef<HTMLInputElement>(null)
const { toast } = useToast()
const selectedStyle = previousPageStyle || "noir"
const selectedStyleId = previousPageStyle || "noir"
const selectedStyle = useMemo(
() => COMIC_STYLES.find((s) => s.id === selectedStyleId)?.name || "Noir",
[selectedStyleId]
)
useEffect(() => {
if (previousCharacters && previousCharacters.length > 0) {
+37 -20
View File
@@ -1,29 +1,39 @@
"use client"
"use client";
import { FileText, ImageIcon, Palette } from "lucide-react"
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@/components/ui/sheet"
import { FileText, ImageIcon, Palette } from "lucide-react";
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
} from "@/components/ui/sheet";
import { COMIC_STYLES } from "@/lib/constants";
interface PageData {
id: number
title: string
image: string
prompt: string
characterUploads?: string[]
style: string
id: number;
title: string;
image: string;
prompt: string;
characterUploads?: string[];
style: string;
}
interface PageInfoSheetProps {
isOpen: boolean
onClose: () => void
page: PageData
isOpen: boolean;
onClose: () => void;
page: PageData;
}
export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
const styleName = COMIC_STYLES.find((s) => s.id === page.style)?.name || page.style;
return (
<Sheet open={isOpen} onOpenChange={onClose}>
<SheetContent className="w-full sm:max-w-md border-l border-border/50 bg-background px-6">
<SheetHeader className="pb-4 border-b border-border/50 px-0">
<SheetTitle className="text-base font-medium text-white">Page {page.id} Details</SheetTitle>
<SheetTitle className="text-base font-medium text-white">
Page {page.id} Details
</SheetTitle>
</SheetHeader>
<div className=" space-y-6">
@@ -34,7 +44,9 @@ export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
<span>Prompt</span>
</div>
<div className="p-3 glass-panel rounded-lg">
<p className="text-sm text-foreground leading-relaxed">{page.prompt}</p>
<p className="text-sm text-foreground leading-relaxed">
{page.prompt}
</p>
</div>
</div>
@@ -45,7 +57,7 @@ export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
<span>Style</span>
</div>
<div className="inline-flex items-center px-3 py-1.5 glass-panel rounded-md">
<span className="text-sm text-foreground">{page.style}</span>
<span className="text-sm text-foreground">{styleName}</span>
</div>
</div>
@@ -57,7 +69,10 @@ export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
{page.characterUploads && page.characterUploads.length > 0 ? (
<div className="flex gap-2">
{page.characterUploads.map((upload, index) => (
<div key={index} className="relative h-24 w-24 rounded-lg overflow-hidden glass-panel">
<div
key={index}
className="relative h-24 w-24 rounded-lg overflow-hidden glass-panel"
>
<img
src={upload || "/placeholder.svg"}
alt={`Uploaded character ${index + 1}`}
@@ -68,12 +83,14 @@ export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
</div>
) : (
<div className="p-4 glass-panel rounded-lg text-center">
<p className="text-sm text-muted-foreground">No characters uploaded</p>
<p className="text-sm text-muted-foreground">
No characters uploaded
</p>
</div>
)}
</div>
{/* Generated Image Preview */}
{/* Generated Image Preview
<div className="space-y-2">
<div className="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
<ImageIcon className="w-3.5 h-3.5" />
@@ -86,9 +103,9 @@ export function PageInfoSheet({ isOpen, onClose, page }: PageInfoSheetProps) {
className="w-full h-full object-cover"
/>
</div>
</div>
</div> */}
</div>
</SheetContent>
</Sheet>
)
);
}