artifacts-dashboard/frontend/src/components/auth/api-key-gate.tsx
Paweł Orzech 10781c7987
Some checks failed
Release / release (push) Has been cancelled
v0.2.0: Rich interactive map, automation gallery, auth & UX improvements
Map overhaul:
- Replace colored boxes with actual game tile images (skin textures from CDN)
- Overlay content icons (monsters, resources, NPCs) on tiles
- Add layer switching (Overworld/Underground/Interior)
- Fix API schema to parse interactions.content and layer fields
- Add hover tooltips, tile search with coordinate parsing, keyboard shortcuts
- Add minimap with viewport rectangle, zoom-toward-cursor, loading progress
- Show tile/content images in side panel, coordinate labels at high zoom

Automation gallery:
- 27+ pre-built automation templates (combat, gathering, crafting, trading, utility)
- Multi-character selection for batch automation creation
- Gallery component with activate dialog

Auth & settings:
- API key gate with auth provider for token management
- Enhanced settings page with token configuration

UI improvements:
- Game icon component for item/monster/resource images
- Character automations panel on character detail page
- Equipment grid and inventory grid enhancements
- Automations page layout refresh
- Bank, exchange page minor fixes
- README update with live demo link
2026-03-01 20:18:29 +01:00

115 lines
3.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { KeyRound, Loader2, ExternalLink } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { useAuth } from "./auth-provider";
export function ApiKeyGate({ children }: { children: React.ReactNode }) {
const { status, loading, setToken } = useAuth();
if (loading) {
return (
<div className="flex h-screen items-center justify-center bg-background">
<Loader2 className="size-8 animate-spin text-muted-foreground" />
</div>
);
}
if (status?.has_token) {
return <>{children}</>;
}
return <ApiKeyForm onSubmit={setToken} />;
}
function ApiKeyForm({
onSubmit,
}: {
onSubmit: (token: string) => Promise<{ success: boolean; error?: string }>;
}) {
const [token, setToken] = useState("");
const [error, setError] = useState<string | null>(null);
const [submitting, setSubmitting] = useState(false);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
if (!token.trim()) return;
setError(null);
setSubmitting(true);
const result = await onSubmit(token.trim());
if (!result.success) {
setError(result.error || "Failed to set token");
}
setSubmitting(false);
}
return (
<div className="flex min-h-screen items-center justify-center bg-background p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<div className="mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-primary/10">
<KeyRound className="size-8 text-primary" />
</div>
<CardTitle className="text-2xl">Artifacts Dashboard</CardTitle>
<p className="text-sm text-muted-foreground mt-2">
Enter your Artifacts MMO API token to get started.
</p>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="api-token">API Token</Label>
<Input
id="api-token"
type="password"
value={token}
onChange={(e) => setToken(e.target.value)}
placeholder="Paste your token here..."
disabled={submitting}
autoFocus
/>
{error && (
<p className="text-sm text-destructive">{error}</p>
)}
</div>
<Button
type="submit"
className="w-full gap-2"
disabled={!token.trim() || submitting}
>
{submitting ? (
<Loader2 className="size-4 animate-spin" />
) : (
<KeyRound className="size-4" />
)}
Connect
</Button>
<p className="text-xs text-center text-muted-foreground">
You can find your token in your{" "}
<a
href="https://artifactsmmo.com/account"
target="_blank"
rel="noopener noreferrer"
className="underline inline-flex items-center gap-0.5 hover:text-foreground"
>
Artifacts MMO account
<ExternalLink className="size-3" />
</a>
. Your token is stored locally in your browser and sent to the
backend server only.
</p>
</form>
</CardContent>
</Card>
</div>
);
}