mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
docs: add VitePress documentation site with GitHub Pages deployment
Rewrites all documentation with accurate project details (Fastify, port 1349, single-container Docker, all 33+ tools, full database schema). Adds getting started guide and configuration reference. Updates help and settings dialogs to link to the docs site.
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
import { useEffect } from "react";
|
||||
import { X, Keyboard, BookOpen, Github, ExternalLink } from "lucide-react";
|
||||
import { APP_VERSION } from "@stirling-image/shared";
|
||||
import { formatShortcut } from "@/hooks/use-keyboard-shortcuts";
|
||||
|
||||
interface HelpDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const SHORTCUTS = [
|
||||
{ keys: "mod+k", description: "Focus search bar" },
|
||||
{ keys: "mod+/", description: "Go to tools" },
|
||||
{ keys: "mod+shift+d", description: "Toggle theme" },
|
||||
{ keys: "mod+alt+1", description: "Go to Resize" },
|
||||
{ keys: "mod+alt+2", description: "Go to Crop" },
|
||||
{ keys: "mod+alt+3", description: "Go to Compress" },
|
||||
{ keys: "mod+alt+4", description: "Go to Convert" },
|
||||
{ keys: "mod+alt+5", description: "Go to Remove Background" },
|
||||
{ keys: "mod+alt+6", description: "Go to Watermark Text" },
|
||||
{ keys: "mod+alt+7", description: "Go to Strip Metadata" },
|
||||
{ keys: "mod+alt+8", description: "Go to Image Info" },
|
||||
];
|
||||
|
||||
export function HelpDialog({ open, onClose }: HelpDialogProps) {
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const handler = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose();
|
||||
};
|
||||
window.addEventListener("keydown", handler);
|
||||
return () => window.removeEventListener("keydown", handler);
|
||||
}, [open, onClose]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div
|
||||
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
|
||||
onClick={onClose}
|
||||
/>
|
||||
|
||||
<div className="relative bg-background border border-border rounded-xl shadow-2xl w-full max-w-lg max-h-[85vh] flex flex-col overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 border-b border-border shrink-0">
|
||||
<h2 className="text-lg font-semibold text-foreground">Help</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="p-1.5 rounded-lg hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 overflow-y-auto p-5 space-y-6">
|
||||
{/* Getting started */}
|
||||
<section className="space-y-2">
|
||||
<div className="flex items-center gap-2 text-foreground">
|
||||
<BookOpen className="h-4 w-4" />
|
||||
<h3 className="text-sm font-semibold">Getting Started</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||
Select a tool from the sidebar or search for one with{" "}
|
||||
<Kbd keys="mod+k" />. Upload an image by dragging it onto the
|
||||
page or clicking the upload area. Adjust settings and download
|
||||
your result.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Keyboard shortcuts */}
|
||||
<section className="space-y-3">
|
||||
<div className="flex items-center gap-2 text-foreground">
|
||||
<Keyboard className="h-4 w-4" />
|
||||
<h3 className="text-sm font-semibold">Keyboard Shortcuts</h3>
|
||||
</div>
|
||||
<div className="rounded-lg border border-border overflow-hidden">
|
||||
{SHORTCUTS.map((s, i) => (
|
||||
<div
|
||||
key={s.keys}
|
||||
className={`flex items-center justify-between px-3 py-2 text-sm ${
|
||||
i !== SHORTCUTS.length - 1
|
||||
? "border-b border-border"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<span className="text-muted-foreground">
|
||||
{s.description}
|
||||
</span>
|
||||
<Kbd keys={s.keys} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Links */}
|
||||
<section className="space-y-2">
|
||||
<div className="flex items-center gap-2 text-foreground">
|
||||
<Github className="h-4 w-4" />
|
||||
<h3 className="text-sm font-semibold">Resources</h3>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<a
|
||||
href="https://github.com/siddharthksah/Stirling-Image"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 text-sm text-primary hover:underline"
|
||||
>
|
||||
GitHub Repository
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/siddharthksah/Stirling-Image/issues"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 text-sm text-primary hover:underline"
|
||||
>
|
||||
Report an Issue
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
<a
|
||||
href="https://siddharthksah.github.io/Stirling-Image/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 text-sm text-primary hover:underline"
|
||||
>
|
||||
Documentation
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
<a
|
||||
href="/api/docs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 text-sm text-primary hover:underline"
|
||||
>
|
||||
API Reference (Swagger)
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Version */}
|
||||
<div className="text-xs text-muted-foreground pt-2 border-t border-border">
|
||||
Stirling Image v{APP_VERSION}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Kbd({ keys }: { keys: string }) {
|
||||
return (
|
||||
<kbd className="px-1.5 py-0.5 rounded bg-muted border border-border text-xs font-mono text-muted-foreground">
|
||||
{formatShortcut(keys)}
|
||||
</kbd>
|
||||
);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ export function SettingsDialog({ open, onClose }: SettingsDialogProps) {
|
||||
/>
|
||||
|
||||
{/* Dialog */}
|
||||
<div className="relative bg-background border border-border rounded-xl shadow-2xl w-full max-w-3xl max-h-[85vh] flex overflow-hidden">
|
||||
<div className="relative bg-background border border-border rounded-xl shadow-2xl w-full max-w-3xl h-[85vh] flex overflow-hidden">
|
||||
{/* Sidebar nav */}
|
||||
<div className="w-48 border-r border-border bg-muted/30 p-3 space-y-1 shrink-0">
|
||||
<div className="flex items-center justify-between mb-4 px-2">
|
||||
@@ -216,8 +216,8 @@ function SystemSection() {
|
||||
const [saveMsg, setSaveMsg] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
apiGet<Record<string, string>>("/v1/settings")
|
||||
.then((data) => setSettings(data))
|
||||
apiGet<{ settings: Record<string, string> }>("/v1/settings")
|
||||
.then((data) => setSettings(data.settings))
|
||||
.catch(() => {
|
||||
// Fallback defaults if endpoint not ready
|
||||
setSettings({
|
||||
@@ -645,8 +645,8 @@ function ApiKeysSection() {
|
||||
|
||||
const loadKeys = useCallback(async () => {
|
||||
try {
|
||||
const data = await apiGet<{ keys: ApiKeyEntry[] }>("/v1/api-keys");
|
||||
setKeys(data.keys);
|
||||
const data = await apiGet<{ apiKeys: ApiKeyEntry[] }>("/v1/api-keys");
|
||||
setKeys(data.apiKeys);
|
||||
} catch {
|
||||
setKeys([]);
|
||||
} finally {
|
||||
@@ -823,13 +823,21 @@ function AboutSection() {
|
||||
>
|
||||
GitHub Repository
|
||||
</a>
|
||||
<a
|
||||
href="https://siddharthksah.github.io/Stirling-Image/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-primary hover:underline"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
<a
|
||||
href="/api/docs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-primary hover:underline"
|
||||
>
|
||||
API Documentation
|
||||
API Reference (Swagger)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user