init
This commit is contained in:
58
components/sync-button.tsx
Normal file
58
components/sync-button.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
"use client";
|
||||
|
||||
import { useActionState } from "react";
|
||||
import { RefreshCw } from "lucide-react";
|
||||
import { submitGarminMfaCode, syncGarminActivities, type SyncGarminState } from "@/app/running/actions";
|
||||
|
||||
export function SyncButton() {
|
||||
const [state, formAction, pending] = useActionState(async () => syncGarminActivities(), null);
|
||||
const [mfaState, mfaAction, mfaPending] = useActionState(
|
||||
async (_prev: SyncGarminState, formData: FormData) => submitGarminMfaCode(String(formData.get("code") ?? "")),
|
||||
null
|
||||
);
|
||||
|
||||
const mfaRequired = (state && "mfaRequired" in state) || (mfaState && "mfaRequired" in mfaState);
|
||||
const activeState = mfaState ?? state;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-end gap-2">
|
||||
<form action={formAction}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={pending}
|
||||
className="flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-semibold text-fg transition-opacity hover:opacity-90 disabled:opacity-50"
|
||||
>
|
||||
<RefreshCw size={16} className={pending ? "animate-spin" : ""} />
|
||||
{pending ? "Synchronizowanie..." : "Synchronizuj z Garmin"}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{mfaRequired ? (
|
||||
<form action={mfaAction} className="flex items-center gap-2">
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputMode="numeric"
|
||||
maxLength={6}
|
||||
placeholder="Kod z e-maila"
|
||||
required
|
||||
className="w-32 rounded-md border border-muted/40 bg-bg px-2 py-1.5 text-sm text-fg"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={mfaPending}
|
||||
className="rounded-md bg-accent px-3 py-1.5 text-sm font-semibold text-fg transition-opacity hover:opacity-90 disabled:opacity-50"
|
||||
>
|
||||
{mfaPending ? "Weryfikacja..." : "Zatwierdź kod"}
|
||||
</button>
|
||||
</form>
|
||||
) : null}
|
||||
|
||||
{mfaRequired ? (
|
||||
<div className="text-sm text-fg/60">Garmin wysłał kod weryfikacyjny na e-mail. Wpisz go powyżej.</div>
|
||||
) : null}
|
||||
{activeState && "error" in activeState ? <div className="text-sm text-accent">{activeState.error}</div> : null}
|
||||
{activeState && "success" in activeState ? <div className="text-sm text-fg/60">{activeState.success}</div> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user