feat: add admin panel, Replicate AI translation, and document translation
- Admin panel (/admin) with JWT auth: configure Replicate API token, JigsawStack API key, model version, enable/disable AI translation, change admin password. Settings persisted in data/settings.json. - Replicate AI translation: POST /api/translate/replicate uses JigsawStack text-translate model via Replicate API. Main page switches to client-side AI translation when enabled. - Document translation tab: supports PDF, DOCX, XLSX, XLS, CSV. Excel/Word formatting fully preserved (SheetJS + JSZip XML manipulation). PDF uses pdf-parse extraction + pdf-lib reconstruction. Column selector UI for tabular data (per-sheet, All/None toggles). - Updated README with full implementation documentation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
38
pages/api/translate/replicate.ts
Normal file
38
pages/api/translate/replicate.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { NextApiHandler } from "next";
|
||||
import NextCors from "nextjs-cors";
|
||||
import { replicateTranslate } from "@utils/replicate-translate";
|
||||
import { readSettings } from "@utils/settings-store";
|
||||
|
||||
type Data = { translation: string } | { error: string };
|
||||
|
||||
const handler: NextApiHandler<Data> = async (req, res) => {
|
||||
await NextCors(req, res, { methods: ["POST"], origin: "*" });
|
||||
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", ["POST"]);
|
||||
return res.status(405).json({ error: "Method Not Allowed" });
|
||||
}
|
||||
|
||||
const settings = readSettings();
|
||||
if (!settings.replicateEnabled) {
|
||||
return res.status(503).json({ error: "Replicate translation is not enabled" });
|
||||
}
|
||||
|
||||
const { text, targetLanguage } = req.body ?? {};
|
||||
if (!text || typeof text !== "string") {
|
||||
return res.status(400).json({ error: "text is required" });
|
||||
}
|
||||
if (!targetLanguage || typeof targetLanguage !== "string") {
|
||||
return res.status(400).json({ error: "targetLanguage is required" });
|
||||
}
|
||||
|
||||
try {
|
||||
const translation = await replicateTranslate(text, targetLanguage);
|
||||
return res.status(200).json({ translation });
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : "Translation failed";
|
||||
return res.status(500).json({ error: msg });
|
||||
}
|
||||
};
|
||||
|
||||
export default handler;
|
||||
Reference in New Issue
Block a user