feat(page): wire image upload state, base64 conversion, and API integration into home page
This commit is contained in:
@@ -21,6 +21,14 @@ import { EventsList } from "@/components/events-list";
|
||||
import { EventDialog } from "@/components/event-dialog";
|
||||
import { DragDropContainer } from "@/components/drag-drop-container";
|
||||
|
||||
const fileToBase64 = (file: File): Promise<string> =>
|
||||
new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result as string);
|
||||
reader.onerror = () => reject(new Error("Failed to read file"));
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
export default function HomePage() {
|
||||
const [events, setEvents] = useState<CalendarEvent[]>([]);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
@@ -45,6 +53,10 @@ export default function HomePage() {
|
||||
const [summary, setSummary] = useState<string | null>(null);
|
||||
const [summaryUpdated, setSummaryUpdated] = useState<string | null>(null);
|
||||
|
||||
// Image
|
||||
const [imageBase64, setImageBase64] = useState<string | null>(null);
|
||||
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const stored = await getAllEvents();
|
||||
@@ -66,6 +78,20 @@ export default function HomePage() {
|
||||
setRecurrenceRule(undefined);
|
||||
};
|
||||
|
||||
const handleImageSelect = async (file: File) => {
|
||||
const base64 = await fileToBase64(file);
|
||||
setImageBase64(base64);
|
||||
setImagePreview(URL.createObjectURL(file));
|
||||
};
|
||||
|
||||
const handleImageClear = () => {
|
||||
if (imagePreview) {
|
||||
URL.revokeObjectURL(imagePreview);
|
||||
}
|
||||
setImageBase64(null);
|
||||
setImagePreview(null);
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
const eventData: CalendarEvent = {
|
||||
id: editingId || nanoid(),
|
||||
@@ -130,7 +156,7 @@ export default function HomePage() {
|
||||
|
||||
// AI Create Event
|
||||
const handleAiCreate = async () => {
|
||||
if (!aiPrompt.trim()) return;
|
||||
if (!aiPrompt.trim() && !imageBase64) return;
|
||||
setAiLoading(true);
|
||||
|
||||
const promise = (): Promise<{ message: string }> =>
|
||||
@@ -139,7 +165,10 @@ export default function HomePage() {
|
||||
const res = await fetch("/api/ai-event", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ prompt: aiPrompt }),
|
||||
body: JSON.stringify({
|
||||
prompt: aiPrompt,
|
||||
imageBase64: imageBase64 || undefined,
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.status === 401) {
|
||||
@@ -154,7 +183,6 @@ export default function HomePage() {
|
||||
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
if (data.length === 1) {
|
||||
// Prefill dialog directly (same as before)
|
||||
const ev = data[0];
|
||||
setTitle(ev.title || "");
|
||||
setDescription(ev.description || "");
|
||||
@@ -167,11 +195,11 @@ export default function HomePage() {
|
||||
setAiPrompt("");
|
||||
setDialogOpen(true);
|
||||
setRecurrenceRule(ev.recurrenceRule || undefined);
|
||||
handleImageClear();
|
||||
resolve({
|
||||
message: "Event has been created!",
|
||||
});
|
||||
} else {
|
||||
// Save them all directly to DB
|
||||
for (const ev of data) {
|
||||
const newEvent = {
|
||||
id: nanoid(),
|
||||
@@ -186,8 +214,9 @@ export default function HomePage() {
|
||||
setAiPrompt("");
|
||||
setSummary(`Added ${data.length} AI-generated events.`);
|
||||
setSummaryUpdated(new Date().toLocaleString());
|
||||
handleImageClear();
|
||||
resolve({
|
||||
message: "Event has been created!",
|
||||
message: "Events have been created!",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -264,6 +293,7 @@ export default function HomePage() {
|
||||
isDragOver={isDragOver}
|
||||
setIsDragOver={setIsDragOver}
|
||||
onImport={handleImport}
|
||||
onImageDrop={handleImageSelect}
|
||||
>
|
||||
<AIToolbar
|
||||
isAuthenticated={!!session?.user}
|
||||
@@ -271,6 +301,9 @@ export default function HomePage() {
|
||||
aiPrompt={aiPrompt}
|
||||
setAiPrompt={setAiPrompt}
|
||||
aiLoading={aiLoading}
|
||||
imagePreview={imagePreview}
|
||||
onImageSelect={handleImageSelect}
|
||||
onImageClear={handleImageClear}
|
||||
onAiCreate={handleAiCreate}
|
||||
onAiSummarize={handleAiSummarize}
|
||||
summary={summary}
|
||||
|
||||
Reference in New Issue
Block a user