| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- "use client";
- /**
- * Shared unlock block — password + eye + clear locked/unlocked messaging.
- */
- import { useState } from "react";
- import { Button } from "@/components/ui/button";
- import { ErrorBanner } from "@/components/ui/error-banner";
- import { PasswordInput } from "@/components/ui/password-input";
- import { unlockVault, type UnlockedMavi } from "@/lib/mavi/storage";
- export function UnlockPanel({
- onUnlocked,
- title = "Unlock mavi",
- description = "Stays unlocked in this browser tab until you lock or close the tab.",
- submitLabel = "Unlock",
- autoFocus,
- }: {
- onUnlocked: (wallet: UnlockedMavi) => void;
- title?: string;
- description?: string;
- submitLabel?: string;
- autoFocus?: boolean;
- }) {
- const [password, setPassword] = useState("");
- const [busy, setBusy] = useState(false);
- const [error, setError] = useState<string | null>(null);
- async function submit() {
- setError(null);
- if (!password) {
- setError("Enter your password.");
- return;
- }
- setBusy(true);
- try {
- const u = await unlockVault(password);
- setPassword("");
- onUnlocked(u);
- } catch (e) {
- setError(
- e instanceof Error
- ? e.message
- : "Wrong password or damaged vault. Try again.",
- );
- } finally {
- setBusy(false);
- }
- }
- return (
- <div className="space-y-3">
- <div>
- <p className="text-sm font-medium text-foreground">{title}</p>
- <p className="mt-1 text-xs text-muted-foreground leading-relaxed">
- {description}
- </p>
- </div>
- {error ? <ErrorBanner title="Could not unlock">{error}</ErrorBanner> : null}
- <PasswordInput
- id="mavi-unlock-shared"
- label="Password"
- value={password}
- onChange={setPassword}
- onEnter={() => void submit()}
- placeholder="Vault password"
- disabled={busy}
- />
- <Button
- type="button"
- className="w-full"
- disabled={busy || password.length < 1}
- onClick={() => void submit()}
- autoFocus={autoFocus}
- >
- {busy ? "Unlocking…" : submitLabel}
- </Button>
- </div>
- );
- }
|