61 lines
3.7 KiB
TypeScript
61 lines
3.7 KiB
TypeScript
"use client";
|
||
import { useState, useTransition } from "react";
|
||
import { CodeOutput } from "@/components/tools/CodeOutput";
|
||
import { regeneratePdfApiKey } from "@/lib/actions/pdf-key-actions";
|
||
import { buildZoteroScript } from "@/lib/clean-pdf/zotero-script";
|
||
|
||
export function ZoteroSection({ apiKey, baseUrl }: { apiKey: string; baseUrl: string }) {
|
||
const [key, setKey] = useState(apiKey);
|
||
const [revealed, setRevealed] = useState(false);
|
||
const [pending, startTransition] = useTransition();
|
||
|
||
const shownKey = revealed ? key : key.slice(0, 8) + "…" + key.slice(-4);
|
||
const curlExample = `curl -H "Authorization: Bearer ${key}" \\\n "${baseUrl}/api/pdf?url=https://example.com/article&format=A4&theme=light" \\\n -o article.pdf`;
|
||
const script = buildZoteroScript({ apiKey: key, baseUrl });
|
||
|
||
function regenerate() {
|
||
if (!confirm("Старый ключ перестанет работать (в том числе в Zotero). Продолжить?")) return;
|
||
startTransition(async () => {
|
||
const res = await regeneratePdfApiKey();
|
||
if (res.ok && res.key) { setKey(res.key); setRevealed(true); }
|
||
});
|
||
}
|
||
|
||
return (
|
||
<div className="flex flex-col gap-4">
|
||
<h2 className="text-lg font-bold" style={{ color: "var(--foreground)" }}>Zotero и API</h2>
|
||
|
||
<div className="flex flex-col gap-2">
|
||
<div className="text-xs font-bold tracking-wide" style={{ color: "var(--muted-foreground)" }}>ВАШ КЛЮЧ</div>
|
||
<div className="flex items-center gap-2">
|
||
<code className="p-2 text-sm" style={{ border: "1px solid var(--border)", borderRadius: "2px" }}>{shownKey}</code>
|
||
<button type="button" className="text-xs underline" onClick={() => setRevealed((v) => !v)}>
|
||
{revealed ? "скрыть" : "показать"}
|
||
</button>
|
||
<button type="button" className="text-xs underline" onClick={() => navigator.clipboard.writeText(key)}>скопировать</button>
|
||
<button type="button" className="text-xs underline" disabled={pending} onClick={regenerate}>
|
||
{pending ? "меняем…" : "перевыпустить"}
|
||
</button>
|
||
</div>
|
||
<p className="text-xs" style={{ color: "var(--muted-foreground)" }}>
|
||
Ключ персональный — не публикуйте его. Если ключ утёк, перевыпустите: старый сразу отключится.
|
||
</p>
|
||
</div>
|
||
|
||
<div className="flex flex-col gap-2 text-sm" style={{ color: "var(--foreground)" }}>
|
||
<div className="text-xs font-bold tracking-wide" style={{ color: "var(--muted-foreground)" }}>НАСТРОЙКА ZOTERO</div>
|
||
<ol className="list-decimal pl-5 flex flex-col gap-1">
|
||
<li>Установите плагин <a className="underline" href="https://github.com/windingwind/zotero-actions-tags/releases" target="_blank" rel="noreferrer">Actions & Tags</a>.</li>
|
||
<li>В настройках плагина нажмите «+» и создайте действие: Name — <b>Чистый PDF</b>, Operation — <b>Script</b>.</li>
|
||
<li>В поле Data вставьте скрипт ниже (ключ уже подставлен).</li>
|
||
<li>Menu Label — <b>_чистый PDF</b>, поставьте галочку <b>In item Menu</b>, нажмите Save.</li>
|
||
<li>Готово: правый клик на записи с URL → «_чистый PDF» — файл прикрепится к записи.</li>
|
||
</ol>
|
||
</div>
|
||
|
||
<CodeOutput code={script} tool="clean-pdf" label="СКРИПТ ДЛЯ ACTIONS & TAGS" />
|
||
<CodeOutput code={curlExample} tool="clean-pdf" label="ПРИМЕР ДЛЯ API (CURL)" />
|
||
</div>
|
||
);
|
||
}
|