bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
100 lines (99 loc) • 7.08 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { CheckIcon } from "@radix-ui/react-icons";
import { useState } from "react";
import { cn } from "../../lib/utils.js";
import { HandCashIcon } from "../ui-components/HandCashIcon.js";
import { Badge } from "../ui/badge.js";
import { Button } from "../ui/button.js";
/**
* Official brand colors for OAuth providers
* These can be used optionally when you want to preserve brand identity
*/
export const OAUTH_BRAND_COLORS = {
google: {
blue: "#4285F4",
green: "#34A853",
yellow: "#FBBC05",
red: "#EA4335",
},
handcash: "#38CB7C",
github: "#24292e",
twitter: "#1DA1F2",
discord: "#5865F2",
facebook: "#1877F2",
microsoft: "#00BCF2",
};
const DEFAULT_PROVIDERS = [
{
id: "google",
name: "Google",
enabled: true,
icon: (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", children: [_jsx("title", { children: "Google" }), _jsxs("g", { fill: "currentColor", children: [_jsx("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }), _jsx("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }), _jsx("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }), _jsx("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })] })] })),
},
{
id: "github",
name: "GitHub",
enabled: true,
icon: (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("title", { children: "GitHub" }), _jsx("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" })] })),
},
{
id: "handcash",
name: "HandCash",
enabled: true,
icon: _jsx(HandCashIcon, {}),
},
{
id: "yours",
name: "Yours Wallet",
enabled: true,
icon: (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("title", { children: "Yours Wallet" }), _jsx("path", { d: "M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5zm0 2.18l8 4v9.82c0 4.28-2.88 8.24-7 9.34V4.18zm-1 5.82v8c-2.55-.9-4.65-3.08-5.58-5.95L11 9.82z" })] })),
},
{
id: "twitter",
name: "X (Twitter)",
enabled: false,
icon: (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("title", { children: "X (Twitter)" }), _jsx("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })] })),
},
];
export function OAuthProviders({ providers = DEFAULT_PROVIDERS, action = "signin", callbackUrl: _callbackUrl, linkedProviders = [], onProviderClick, disabled = false, loading = false, className = "", size: _size = "2", }) {
const [clickedProvider, setClickedProvider] = useState(null);
const handleProviderClick = async (providerId) => {
if (disabled || loading)
return;
setClickedProvider(providerId);
try {
if (onProviderClick) {
await onProviderClick(providerId);
}
}
finally {
setClickedProvider(null);
}
};
// Filter to only enabled providers
const enabledProviders = providers.filter((p) => p.enabled !== false);
if (enabledProviders.length === 0) {
return (_jsx("div", { className: cn("flex flex-col items-center gap-2", className), children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No OAuth providers configured" }) }));
}
const getActionText = (provider, isLinked) => {
if (isLinked)
return "Linked";
switch (action) {
case "signin":
return `Continue with ${provider.name}`;
case "signup":
return `Sign up with ${provider.name}`;
case "link":
return `Link ${provider.name}`;
default:
return `Continue with ${provider.name}`;
}
};
return (_jsxs("div", { className: cn("flex flex-col gap-3", className), children: [enabledProviders.map((provider) => {
const isLinked = linkedProviders.includes(provider.id);
const isClicked = clickedProvider === provider.id;
const isDisabled = disabled || loading || isLinked;
return (_jsx(Button, { "data-provider": provider.id, variant: isLinked ? "secondary" : "outline", size: "lg", disabled: isDisabled, onClick: () => handleProviderClick(provider.id), className: cn("w-full justify-start p-4 transition-all", isLinked && "border-green-500", isDisabled && "cursor-not-allowed"), children: _jsxs("div", { className: "flex items-center gap-3 w-full", children: [_jsx("div", { className: cn("shrink-0 w-6 h-6 flex items-center justify-center", isLinked ? "text-green-600" : "text-foreground"), children: isClicked ? (_jsx("div", { className: "animate-spin w-5 h-5", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", "aria-label": "Loading", children: [_jsx("title", { children: "Loading" }), _jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", className: "opacity-25" }), _jsx("path", { fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z", className: "opacity-75" })] }) })) : (provider.icon) }), _jsx("span", { className: "flex-1 text-left text-base font-medium", children: getActionText(provider, isLinked) }), isLinked && (_jsx(Badge, { variant: "secondary", className: "bg-green-100 text-green-800", children: _jsx(CheckIcon, { width: "12", height: "12" }) }))] }) }, provider.id));
}), action === "signin" && enabledProviders.length > 0 && (_jsx("p", { className: "text-xs text-muted-foreground text-center mt-2", children: "By continuing, you agree to our Terms of Service and Privacy Policy" }))] }));
}