@particle-network/connectkit
Version:
789 lines (778 loc) • 24.3 kB
JavaScript
"use client";
import {
init_useWalletConnectors,
useWalletConnector
} from "./chunk-AQVZSU2R.mjs";
import {
PageContent,
init_styles
} from "./chunk-QH6JFFQS.mjs";
import {
PhoneIcon_default,
init_PhoneIcon
} from "./chunk-6Y7ITC2N.mjs";
import {
EmailIcon_default,
init_EmailIcon
} from "./chunk-AOANHEXC.mjs";
import "./chunk-ONDUNK5K.mjs";
import {
circleSpinner_default,
init_circleSpinner
} from "./chunk-LPKOMA4X.mjs";
import {
init_useConnect,
useConnect
} from "./chunk-I7EXWVJH.mjs";
import "./chunk-XV4TVGGP.mjs";
import {
init_useConnectors,
useConnector
} from "./chunk-QGF3ZKLH.mjs";
import {
init_context,
init_useAppearance,
init_useLocales,
init_useModalError,
init_useRouter,
useAppearance,
useContext,
useLocales,
useModalError,
useRouter
} from "./chunk-ODGVUXUQ.mjs";
import "./chunk-CVABX3CN.mjs";
import "./chunk-N5ZSWBVC.mjs";
import "./chunk-D7QF5CYD.mjs";
import "./chunk-TVDFKXAV.mjs";
import "./chunk-4YAFPODW.mjs";
import "./chunk-NITEP4FF.mjs";
import "./chunk-WYWSNAPC.mjs";
import "./chunk-X3AHMJH4.mjs";
import "./chunk-VM42Y624.mjs";
import "./chunk-3CZRO6RQ.mjs";
import "./chunk-2LQKVNKI.mjs";
import "./chunk-CNE7WI2P.mjs";
import "./chunk-HKMLJP4P.mjs";
import "./chunk-VW7L52Q6.mjs";
import "./chunk-BG2VLRRD.mjs";
import "./chunk-5TAT3MVW.mjs";
import "./chunk-AOBFG4R6.mjs";
import "./chunk-KD3UOOP5.mjs";
import "./chunk-VYUWVCC2.mjs";
import "./chunk-HHHJM4FL.mjs";
import "./chunk-743HT6GA.mjs";
import "./chunk-3JW6NUP7.mjs";
import "./chunk-Y2AM7F32.mjs";
import "./chunk-4EX26J4C.mjs";
import "./chunk-QT4CBCFK.mjs";
import "./chunk-3OVTLX5O.mjs";
import "./chunk-5VTAF6IK.mjs";
import "./chunk-5KG67Q3H.mjs";
import "./chunk-PSUGDD7L.mjs";
import "./chunk-MEE5TGUN.mjs";
import {
__esm
} from "./chunk-Y7A564BU.mjs";
// src/components/codeInput/styles.ts
import { styled } from "styled-components";
var CodeInputContainer, CodeInputMask, StyleCodeInputItem, FocusBorder;
var init_styles2 = __esm({
"src/components/codeInput/styles.ts"() {
"use strict";
CodeInputContainer = styled.div`
width: 100%;
max-width: 340px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
display: inline-block;
margin: auto;
width: auto;
position: relative;
left: 50%;
transform: translateX(-50%);
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
box-shadow: 0 0 0 60px var(--pcm-body-background) inset !important;
-webkit-text-fill-color: var(--pcm-body-color) !important;
}
`;
CodeInputMask = styled.div`
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
cursor: pointer;
`;
StyleCodeInputItem = styled.input`
width: 42px;
height: 42px;
padding: 0;
margin-right: 5px;
margin-left: 5px;
border: transparent;
border-radius: var(--pcm-rounded-md);
font-size: 20px;
text-align: center;
text-transform: uppercase;
background-clip: padding-box;
caret-color: var(--pcm-primary-color);
color: ${({ error }) => error ? "var(--pcm-error-color)" : "var(--pcm-body-color)"};
background-color: ${({ error }) => error ? "var(--pcm-error-background)" : "var(--pcm-body-background-secondary)"};
border: none;
&:focus,
&:active,
&:hover,
&:visited,
&:focus-visible {
appearance: none;
outline: none !important;
border: none !important;
}
&:not(:placeholder-shown) {
appearance: none;
outline: 0;
}
`;
FocusBorder = styled.div`
position: absolute;
top: 0;
opacity: ${({ $showFocusBorder }) => $showFocusBorder ? 1 : 0};
left: ${({ $focusIndex }) => 5 + $focusIndex * 52}px;
width: 42px;
height: 42px;
border: 1px solid var(--pcm-accent-color);
border-radius: var(--pcm-rounded-md);
transition:
left 0.3s ease,
opacity 0.2s ease;
pointer-events: none;
z-index: 2;
`;
}
});
// src/components/codeInput/index.tsx
import React, { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
var allowedCharactersValues, propsMap, CodeInput, codeInput_default;
var init_codeInput = __esm({
"src/components/codeInput/index.tsx"() {
"use strict";
init_styles2();
allowedCharactersValues = ["alpha", "numeric", "alphanumeric"];
propsMap = {
alpha: {
type: "text",
inputMode: "text",
pattern: "[a-zA-Z]{1}"
},
alphanumeric: {
type: "text",
inputMode: "text",
pattern: "[a-zA-Z0-9]{1}"
},
numeric: {
type: "tel",
inputMode: "numeric",
pattern: "[0-9]{1}",
min: "0",
max: "9"
}
};
CodeInput = forwardRef(
({
allowedCharacters = "alphanumeric",
ariaLabel,
autoFocus = true,
disabled,
isPassword = false,
length = 6,
placeholder,
onChange,
code = "",
error = ""
}, ref) => {
if (isNaN(length) || length < 1) {
throw new Error("Length should be a number and greater than 0");
}
if (!allowedCharactersValues.some((value) => value === allowedCharacters)) {
throw new Error("Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric");
}
const [focusIndex, setFocusIndex] = React.useState(0);
const [showFocusBorder, setShowFocusBorder] = React.useState(false);
const inputsRef = useRef([]);
const inputProps = propsMap[allowedCharacters];
const codeInputContainerRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
if (inputsRef.current) {
inputsRef.current[0]?.focus();
}
},
clear: () => {
if (inputsRef.current) {
for (let i = 0; i < inputsRef.current.length; i++) {
if (inputsRef.current?.[i]) {
inputsRef.current[i].value = "";
}
}
inputsRef.current[0].focus();
}
sendResult();
}
}));
useEffect(() => {
if (code) {
for (let i = 0; i < inputsRef.current.length; i++) {
inputsRef.current[i].value = "";
}
for (let i = 0; i < code.length; i++) {
if (inputsRef.current?.[i]) {
inputsRef.current[i].value = code[i] || "";
}
}
sendResult();
}
}, [code]);
let oldValue = inputsRef.current.map((input) => input.value).join("") || "";
const sendResult = () => {
const res = inputsRef.current.map((input) => input.value).join("");
if (oldValue !== res) {
if (res.length === 6) {
setTimeout(() => {
inputsRef.current.forEach((input) => {
input.blur();
});
}, 400);
}
onChange && onChange(res);
oldValue = res;
}
};
const handleOnChange = (e) => {
const {
target: { value, nextElementSibling }
} = e;
if (value.length == 1) {
if (value.match(inputProps.pattern)) {
if (nextElementSibling !== null) {
nextElementSibling.focus();
}
} else {
e.target.value = "";
}
} else if (value.length > 1) {
const pastedValue = value;
let currentInput = Number(e.target.getAttribute("data-index")) || 0;
for (let i = 0; i < pastedValue.length; i++) {
const pastedCharacter = pastedValue.charAt(i);
if (pastedCharacter.match(inputProps.pattern) && inputsRef.current?.[currentInput]) {
inputsRef.current[currentInput].value = pastedCharacter;
if (inputsRef.current[currentInput].nextElementSibling !== null) {
inputsRef.current[currentInput].nextElementSibling.focus();
currentInput++;
}
}
}
}
setTimeout(() => {
sendResult();
});
};
const handleOnKeyDown = (e) => {
const { key } = e;
const target = e.target;
if (key === "Backspace") {
if (target.value === "") {
if (target.previousElementSibling !== null) {
const t = target.previousElementSibling;
t.value = "";
t.focus();
e.preventDefault();
}
} else {
target.value = "";
}
setTimeout(() => {
sendResult();
});
}
};
const handleOnFocus = (e) => {
e.target.select();
};
const handleOnPaste = (e) => {
let pastedValue = e.clipboardData.getData("Text") ?? "";
pastedValue = pastedValue.replace(/\s/g, "").substring(0, 6);
let currentInputIndex = focusIndex;
for (let i = 0; i < pastedValue.length; i++) {
const pastedCharacter = pastedValue.charAt(i);
const currentInput = inputsRef.current[currentInputIndex];
if (!currentInput) {
break;
}
const currentValue = currentInput?.value;
if (pastedCharacter.match(inputProps.pattern)) {
if (!currentValue) {
inputsRef.current[currentInputIndex].value = pastedCharacter;
if (inputsRef.current[currentInputIndex].nextElementSibling !== null) {
inputsRef.current[currentInputIndex].nextElementSibling.focus();
currentInputIndex++;
}
}
}
}
sendResult();
e.preventDefault();
};
return /* @__PURE__ */ jsxs(CodeInputContainer, { ref: codeInputContainerRef, children: [
/* @__PURE__ */ jsx(FocusBorder, { $focusIndex: focusIndex, $showFocusBorder: showFocusBorder }),
new Array(6).fill(0).map((_, i) => {
return /* @__PURE__ */ jsx(
StyleCodeInputItem,
{
"data-index": i,
onChange: handleOnChange,
onKeyDown: handleOnKeyDown,
onFocus: (e) => {
setShowFocusBorder(true);
setFocusIndex(i);
handleOnFocus(e);
},
autoFocus: autoFocus && i === 0,
onBlur: () => {
setShowFocusBorder(false);
},
onPaste: handleOnPaste,
...inputProps,
type: isPassword ? "password" : inputProps.type,
ref: (el) => {
inputsRef.current[i] = el;
},
autoComplete: i === 0 ? "one-time-code" : "off",
"aria-label": ariaLabel ? `${ariaLabel}. Character ${i + 1}.` : `Character ${i + 1}.`,
disabled,
placeholder,
error
},
i
);
}),
/* @__PURE__ */ jsx(
CodeInputMask,
{
onClick: (e) => {
e.preventDefault();
e.stopPropagation();
for (let i = inputsRef.current.length - 1; i >= 0; i--) {
if (i > 0 && !inputsRef.current[i].value && inputsRef.current[i - 1].value || i === 0 && !inputsRef.current[i].value || i == inputsRef.current.length - 1 && inputsRef.current[i].value) {
inputsRef.current[i].focus();
inputsRef.current[i].setSelectionRange(
inputsRef.current[i].value.length,
inputsRef.current[i].value.length
);
break;
}
}
}
}
)
] });
}
);
codeInput_default = CodeInput;
}
});
// src/components/loadingSpinner/styles.ts
import { motion } from "framer-motion";
import { styled as styled2 } from "styled-components";
var StyledSpinnerContainer, StyledSpinnerCircle;
var init_styles3 = __esm({
"src/components/loadingSpinner/styles.ts"() {
"use strict";
StyledSpinnerContainer = styled2(motion.div)`
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
`;
StyledSpinnerCircle = styled2(motion.div)`
box-sizing: border-box;
display: block;
position: absolute;
width: ${(props) => props.width};
height: ${(props) => props.height};
margin: 6px;
border-style: solid;
border-radius: 50%;
animation: spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
`;
}
});
// src/components/loadingSpinner/index.tsx
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
var LoadingSpinner, loadingSpinner_default;
var init_loadingSpinner = __esm({
"src/components/loadingSpinner/index.tsx"() {
"use strict";
init_styles3();
LoadingSpinner = ({
size = "50%",
borderColor = "#a748ff",
borderWidth = 3,
spin = false,
children
}) => {
return /* @__PURE__ */ jsxs2(StyledSpinnerContainer, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, children: [
spin && /* @__PURE__ */ jsx2(Fragment, { children: [...Array(4)].map((_, index) => /* @__PURE__ */ jsx2(
StyledSpinnerCircle,
{
width: size,
height: size,
style: {
animationDelay: `-${index * 0.15}s`,
borderWidth,
borderColor: `${borderColor} transparent transparent transparent`
}
},
index
)) }),
/* @__PURE__ */ jsx2(
"div",
{
style: {
opacity: spin ? 0.05 : 1
},
children
}
)
] });
};
loadingSpinner_default = LoadingSpinner;
}
});
// src/components/reSend/styles.ts
import { styled as styled3 } from "styled-components";
var ReSendCodeWrap, ReSendCodeDiv;
var init_styles4 = __esm({
"src/components/reSend/styles.ts"() {
"use strict";
ReSendCodeWrap = styled3.div`
text-align: center;
margin-top: 40px;
color: var(--pcm-body-color-secondary);
font-size: 14px;
`;
ReSendCodeDiv = styled3.div`
color: var(--pcm-accent-color);
margin-top: 6px;
cursor: ${({ $pointer }) => $pointer ? "pointer" : "default"};
display: flex;
gap: 0px;
align-items: center;
width: 100%;
justify-content: center;
position: relative;
height: 24px;
`;
}
});
// src/components/reSend/index.tsx
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
var DownTime, ReSend, reSend_default;
var init_reSend = __esm({
"src/components/reSend/index.tsx"() {
"use strict";
init_useLocales();
init_useModalError();
init_loadingSpinner();
init_styles4();
DownTime = 60;
ReSend = ({ reSendCode }) => {
const locales = useLocales();
const [downTimeStatus, setDownTimeStatus] = useState(0 /* NotStarted */);
const { showError } = useModalError();
const [downTime, setDownTime] = useState(DownTime);
const [loading, setLoading] = useState(false);
const timerRef = useRef2(null);
const downTimeCount = () => {
setDownTime(DownTime);
setDownTimeStatus(1 /* InProgress */);
timerRef.current = setInterval(() => {
setDownTime((val) => {
const newVal = val - 1;
if (newVal === 0) {
setDownTimeStatus(2 /* End */);
clearInterval(timerRef.current);
}
return newVal;
});
}, 1e3);
};
const reSendCodeHandler = async () => {
try {
if (loading)
return;
setLoading(true);
if (downTimeStatus === 2 /* End */) {
await reSendCode();
downTimeCount();
}
} catch (error) {
showError(error?.message || "");
}
setTimeout(() => {
setLoading(false);
}, 100);
};
useEffect2(() => {
downTimeCount();
return () => {
clearInterval(timerRef.current);
};
}, []);
return /* @__PURE__ */ jsx3(ReSendCodeWrap, { children: downTimeStatus !== 0 /* NotStarted */ && /* @__PURE__ */ jsxs3("div", { children: [
locales.didNotReceiveCode,
/* @__PURE__ */ jsx3(ReSendCodeDiv, { $pointer: downTimeStatus === 2 /* End */, children: downTimeStatus === 1 /* InProgress */ || downTimeStatus === 3 /* Stop */ ? `${downTime} s` : downTimeStatus === 2 /* End */ ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
loading && /* @__PURE__ */ jsx3(
"div",
{
style: {
width: "24px",
height: "24px",
top: "1px",
position: "relative"
},
children: /* @__PURE__ */ jsx3(loadingSpinner_default, { spin: true, borderWidth: 2 })
}
),
/* @__PURE__ */ jsx3("div", { onClick: reSendCodeHandler, children: locales.resendCode })
] }) : "" })
] }) });
};
reSend_default = ReSend;
}
});
// src/pages/captcha/styles.ts
import { styled as styled4 } from "styled-components";
var EmailCaptchaWrapper, EmailErrorContent, EmailError, EmailErrorLeft, EmailErrorRight, EmailCaptchaTip1, EmailText, EmailMainIcon, EmailInfo, EmailIconDiv, Spin;
var init_styles5 = __esm({
"src/pages/captcha/styles.ts"() {
"use strict";
EmailCaptchaWrapper = styled4.div`
position: relative;
padding-top: 10px;
`;
EmailErrorContent = styled4.div`
position: relative;
width: 96%;
left: 2%;
top: 0;
margin-bottom: 30px;
`;
EmailError = styled4.div`
background: var(--pcm-error-background);
border-radius: 28px;
line-height: 1;
display: flex;
align-items: center;
color: var(--pcm-error-color);
padding: 8px 8px;
line-height: 1.2;
display: flex;
`;
EmailErrorLeft = styled4.div`
min-width: 20px;
width: 20px;
`;
EmailErrorRight = styled4.div`
flex: 1;
font-size: 12px;
`;
EmailCaptchaTip1 = styled4.div`
font-size: 14px;
`;
EmailText = styled4.div`
font-size: 14px;
font-weight: bold;
margin-top: 4px;
`;
EmailMainIcon = styled4.div`
margin: auto;
display: flex;
justify-content: center;
margin-bottom: 30px;
height: 80px;
position: relative;
`;
EmailInfo = styled4.div`
text-align: center;
margin-bottom: 30px;
`;
EmailIconDiv = styled4.div`
position: relative;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
`;
Spin = styled4.div`
display: inline-block;
animation: spin 1.2s linear infinite;
position: absolute;
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`;
}
});
// src/pages/captcha/index.tsx
import { isEVMChain } from "@particle-network/connector-core";
import { useRef as useRef3, useState as useState2 } from "react";
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
var Page, captcha_default;
var init_captcha = __esm({
"src/pages/captcha/index.tsx"() {
init_EmailIcon();
init_PhoneIcon();
init_circleSpinner();
init_codeInput();
init_styles();
init_reSend();
init_context();
init_useAppearance();
init_useConnect();
init_useConnectors();
init_useLocales();
init_useModalError();
init_useRouter();
init_useWalletConnectors();
init_styles5();
Page = ({ value, type }) => {
const locales = useLocales();
const { config } = useContext();
const { error, showError } = useModalError();
const connector = useConnector(isEVMChain(config.chains[0]) ? "particleEVM" : "particleSolana");
const { connectAsync } = useConnect();
const { appearance } = useAppearance();
const [loading, setLoading] = useState2(false);
const emailCaptchaWrapperRef = useRef3(null);
const walletConnector = useWalletConnector("particleAuth");
const { navigate } = useRouter();
const loginHandler = async (params) => {
await connectAsync({ connector, authParams: params });
};
const onCodeInputChange = async (code) => {
try {
if (loading)
return;
if (code.length === 6) {
if (/![^0-9]/.test(code)) {
throw new Error(locales.incorrectCode);
} else {
setLoading(true);
const params = {
code,
...type === "phone" /* Phone */ ? { phone: value } : { email: value }
};
if (!params.code) {
throw new Error("Please enter the verification code");
} else if (!params.phone && !params.email) {
throw new Error("Please enter the phone number or email");
}
await loginHandler(params);
}
} else {
showError("");
}
} catch (error2) {
let message = error2?.extra?.[0] || error2.message || (typeof error2 === "string" ? error2 : locales.networkError);
if (message.includes("Invalid code")) {
message = locales.invalidCode;
} else if (message.includes("Code is deleted")) {
message = locales.codeDeleted;
} else if (message.includes("Network Error")) {
message = locales.networkError;
}
if (error2.code === 4011) {
navigate("signup" /* Signup */);
setTimeout(() => showError(message));
} else {
showError(message);
}
}
setLoading(false);
};
const reSendCode = async () => {
let turnstileToken = "";
if (type === "phone" /* Phone */) {
turnstileToken = await walletConnector?.auth.getCloudflareTurnstileResponse({
theme: appearance.mode || "lgiht",
language: appearance.language || "en",
getContainer: emailCaptchaWrapperRef.current
});
}
const params = type === "phone" /* Phone */ ? {
phone: value,
cf_turnstile_response: turnstileToken
} : { email: value };
await walletConnector?.auth.getConnectCaptcha(params);
};
return /* @__PURE__ */ jsx4(
PageContent,
{
style: {
padding: "12px 2px 8px"
},
children: /* @__PURE__ */ jsxs4(EmailCaptchaWrapper, { ref: emailCaptchaWrapperRef, children: [
/* @__PURE__ */ jsx4(EmailMainIcon, { children: /* @__PURE__ */ jsx4(
circleSpinner_default,
{
width: 70,
height: 70,
inset: 2,
logo: /* @__PURE__ */ jsx4(EmailIconDiv, { children: type === "phone" ? /* @__PURE__ */ jsx4(PhoneIcon_default, {}) : /* @__PURE__ */ jsx4(EmailIcon_default, {}) })
}
) }),
/* @__PURE__ */ jsxs4(EmailInfo, { children: [
/* @__PURE__ */ jsx4(EmailCaptchaTip1, { children: locales.verificationCode }),
/* @__PURE__ */ jsx4(EmailText, { children: value })
] }),
/* @__PURE__ */ jsx4(
codeInput_default,
{
allowedCharacters: "numeric",
length: 6,
placeholder: " ",
onChange: onCodeInputChange,
error: error || ""
}
),
/* @__PURE__ */ jsx4(reSend_default, { reSendCode })
] })
}
);
};
captcha_default = Page;
}
});
init_captcha();
export {
captcha_default as default
};
//# sourceMappingURL=captcha-6UGSIUEZ.mjs.map