Files
openpylon/src/components/import-export/ImportExportButtons.tsx
T
Your Name 414c1f7d68 feat: typography overhaul, custom scrollbars, import/export, settings UI
Includes changes from prior sessions: Epilogue + Space Mono fonts,
OverlayScrollbars integration, markdown editor fixes, settings dialog,
import/export buttons, and various UI refinements.
2026-02-16 14:56:36 +02:00

75 lines
2.2 KiB
TypeScript

import { useRef } from "react";
import { Upload } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useAppStore } from "@/stores/app-store";
import { useBoardStore } from "@/stores/board-store";
import { useToastStore } from "@/stores/toast-store";
import { saveBoard } from "@/lib/storage";
import {
importBoardFromJson,
importFromTrelloJson,
} from "@/lib/import-export";
export function ImportButton() {
const fileInputRef = useRef<HTMLInputElement>(null);
const addToast = useToastStore((s) => s.addToast);
const refreshBoards = useAppStore((s) => s.refreshBoards);
const setView = useAppStore((s) => s.setView);
const addRecentBoard = useAppStore((s) => s.addRecentBoard);
const openBoard = useBoardStore((s) => s.openBoard);
function handleImportClick() {
fileInputRef.current?.click();
}
async function handleFileSelected(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0];
if (!file) return;
try {
const text = await file.text();
let imported;
// Try to detect if it's a Trello export
const parsed = JSON.parse(text);
if (parsed.lists && parsed.cards && !parsed.columns) {
// Looks like Trello format
imported = importFromTrelloJson(text);
} else {
imported = importBoardFromJson(text);
}
await saveBoard(imported);
await refreshBoards();
await openBoard(imported.id);
setView({ type: "board", boardId: imported.id });
addRecentBoard(imported.id);
addToast("Board imported successfully", "success");
} catch (err) {
console.error("Import failed:", err);
addToast("Import failed — check file format", "error");
}
// Reset the input so the same file can be re-imported
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
}
return (
<>
<Button variant="outline" size="sm" onClick={handleImportClick}>
<Upload className="size-4" />
Import
</Button>
<input
ref={fileInputRef}
type="file"
accept=".json"
onChange={handleFileSelected}
className="hidden"
/>
</>
);
}