@dravyn/auth-ui 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-35G4WYX3.mjs +154 -0
- package/dist/chunk-35G4WYX3.mjs.map +1 -0
- package/dist/chunk-6BBGRN4E.mjs +1 -0
- package/dist/chunk-6BBGRN4E.mjs.map +1 -0
- package/dist/chunk-FAI3ERB3.mjs +209 -0
- package/dist/chunk-FAI3ERB3.mjs.map +1 -0
- package/dist/chunk-FVXZZTKL.mjs +152 -0
- package/dist/chunk-FVXZZTKL.mjs.map +1 -0
- package/dist/chunk-Z2ICX4UY.mjs +132 -0
- package/dist/chunk-Z2ICX4UY.mjs.map +1 -0
- package/dist/index.css +235 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +678 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +22 -0
- package/dist/index.mjs.map +1 -0
- package/dist/screens/ForgotResetScreen.css +235 -0
- package/dist/screens/ForgotResetScreen.css.map +1 -0
- package/dist/screens/ForgotResetScreen.d.mts +17 -0
- package/dist/screens/ForgotResetScreen.d.ts +17 -0
- package/dist/screens/ForgotResetScreen.js +245 -0
- package/dist/screens/ForgotResetScreen.js.map +1 -0
- package/dist/screens/ForgotResetScreen.mjs +11 -0
- package/dist/screens/ForgotResetScreen.mjs.map +1 -0
- package/dist/screens/LoginScreen.css +235 -0
- package/dist/screens/LoginScreen.css.map +1 -0
- package/dist/screens/LoginScreen.d.mts +36 -0
- package/dist/screens/LoginScreen.d.ts +36 -0
- package/dist/screens/LoginScreen.js +167 -0
- package/dist/screens/LoginScreen.js.map +1 -0
- package/dist/screens/LoginScreen.mjs +9 -0
- package/dist/screens/LoginScreen.mjs.map +1 -0
- package/dist/screens/OTPScreen.css +235 -0
- package/dist/screens/OTPScreen.css.map +1 -0
- package/dist/screens/OTPScreen.d.mts +16 -0
- package/dist/screens/OTPScreen.d.ts +16 -0
- package/dist/screens/OTPScreen.js +187 -0
- package/dist/screens/OTPScreen.js.map +1 -0
- package/dist/screens/OTPScreen.mjs +9 -0
- package/dist/screens/OTPScreen.mjs.map +1 -0
- package/dist/screens/RegisterScreen.css +235 -0
- package/dist/screens/RegisterScreen.css.map +1 -0
- package/dist/screens/RegisterScreen.d.mts +21 -0
- package/dist/screens/RegisterScreen.d.ts +21 -0
- package/dist/screens/RegisterScreen.js +189 -0
- package/dist/screens/RegisterScreen.js.map +1 -0
- package/dist/screens/RegisterScreen.mjs +9 -0
- package/dist/screens/RegisterScreen.mjs.map +1 -0
- package/package.json +39 -0
- package/src/screens/auth.css +260 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/screens/OTPScreen.tsx
|
|
32
|
+
var OTPScreen_exports = {};
|
|
33
|
+
__export(OTPScreen_exports, {
|
|
34
|
+
OTPScreen: () => OTPScreen
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(OTPScreen_exports);
|
|
37
|
+
var import_react = __toESM(require("react"));
|
|
38
|
+
var import_ui = require("@dravyn/ui");
|
|
39
|
+
var import_ui2 = require("@dravyn/ui");
|
|
40
|
+
var OTPScreen = ({
|
|
41
|
+
email: emailProp,
|
|
42
|
+
redirectTo = "/dashboard",
|
|
43
|
+
onSuccess,
|
|
44
|
+
logo,
|
|
45
|
+
brandName = "Dravyn",
|
|
46
|
+
apiBase = process.env.NEXT_PUBLIC_AUTH_API_URL ?? "http://localhost:3001",
|
|
47
|
+
length = 6
|
|
48
|
+
}) => {
|
|
49
|
+
const email = emailProp ?? (typeof sessionStorage !== "undefined" ? sessionStorage.getItem("dravyn_pending_email") ?? "" : "");
|
|
50
|
+
const [otp, setOtp] = import_react.default.useState(Array(length).fill(""));
|
|
51
|
+
const [loading, setLoading] = import_react.default.useState(false);
|
|
52
|
+
const [resending, setResending] = import_react.default.useState(false);
|
|
53
|
+
const [error, setError] = import_react.default.useState("");
|
|
54
|
+
const [success, setSuccess] = import_react.default.useState("");
|
|
55
|
+
const [countdown, setCountdown] = import_react.default.useState(60);
|
|
56
|
+
const inputRefs = import_react.default.useRef([]);
|
|
57
|
+
import_react.default.useEffect(() => {
|
|
58
|
+
if (countdown <= 0) return;
|
|
59
|
+
const t = setTimeout(() => setCountdown((c) => c - 1), 1e3);
|
|
60
|
+
return () => clearTimeout(t);
|
|
61
|
+
}, [countdown]);
|
|
62
|
+
import_react.default.useEffect(() => {
|
|
63
|
+
inputRefs.current[0]?.focus();
|
|
64
|
+
}, []);
|
|
65
|
+
const handleInput = (i, val) => {
|
|
66
|
+
if (val.length > 1) {
|
|
67
|
+
const digits = val.replace(/\D/g, "").slice(0, length).split("");
|
|
68
|
+
const next2 = [...otp];
|
|
69
|
+
digits.forEach((d, idx) => {
|
|
70
|
+
if (idx < length) next2[idx] = d;
|
|
71
|
+
});
|
|
72
|
+
setOtp(next2);
|
|
73
|
+
const last = Math.min(digits.length, length - 1);
|
|
74
|
+
inputRefs.current[last]?.focus();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const digit = val.replace(/\D/g, "");
|
|
78
|
+
const next = [...otp];
|
|
79
|
+
next[i] = digit;
|
|
80
|
+
setOtp(next);
|
|
81
|
+
if (digit && i < length - 1) inputRefs.current[i + 1]?.focus();
|
|
82
|
+
};
|
|
83
|
+
const handleKeyDown = (i, e) => {
|
|
84
|
+
if (e.key === "Backspace" && !otp[i] && i > 0) {
|
|
85
|
+
inputRefs.current[i - 1]?.focus();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const handleVerify = async () => {
|
|
89
|
+
const code = otp.join("");
|
|
90
|
+
if (code.length < length) {
|
|
91
|
+
setError("Enter the complete verification code.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
setLoading(true);
|
|
95
|
+
setError("");
|
|
96
|
+
try {
|
|
97
|
+
const res = await fetch(`${apiBase}/auth/verify-otp`, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "Content-Type": "application/json" },
|
|
100
|
+
body: JSON.stringify({ email, otp: code })
|
|
101
|
+
});
|
|
102
|
+
const data = await res.json();
|
|
103
|
+
if (!res.ok) {
|
|
104
|
+
setError(data.message ?? "Invalid or expired code.");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
sessionStorage.removeItem("dravyn_pending_email");
|
|
108
|
+
if (data.accessToken) {
|
|
109
|
+
localStorage.setItem("dravyn_token", data.accessToken);
|
|
110
|
+
localStorage.setItem("dravyn_user", JSON.stringify(data.user));
|
|
111
|
+
}
|
|
112
|
+
if (onSuccess) onSuccess();
|
|
113
|
+
else window.location.href = redirectTo;
|
|
114
|
+
} catch {
|
|
115
|
+
setError("Unable to connect.");
|
|
116
|
+
} finally {
|
|
117
|
+
setLoading(false);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const handleResend = async () => {
|
|
121
|
+
setResending(true);
|
|
122
|
+
setError("");
|
|
123
|
+
setSuccess("");
|
|
124
|
+
try {
|
|
125
|
+
const res = await fetch(`${apiBase}/auth/resend-otp`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers: { "Content-Type": "application/json" },
|
|
128
|
+
body: JSON.stringify({ email })
|
|
129
|
+
});
|
|
130
|
+
if (res.ok) {
|
|
131
|
+
setSuccess("A new code has been sent to your email.");
|
|
132
|
+
setCountdown(60);
|
|
133
|
+
setOtp(Array(length).fill(""));
|
|
134
|
+
inputRefs.current[0]?.focus();
|
|
135
|
+
} else {
|
|
136
|
+
setError("Could not resend. Try again shortly.");
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
setError("Unable to connect.");
|
|
140
|
+
} finally {
|
|
141
|
+
setResending(false);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-root" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-card" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-brand" }, logo ?? /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-logo-default" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "dauth-logo-dot" }), brandName)), /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-otp-icon", "aria-hidden": "true" }, "\u2709"), /* @__PURE__ */ import_react.default.createElement("h1", { className: "dauth-title" }, "Check your email"), /* @__PURE__ */ import_react.default.createElement("p", { className: "dauth-sub" }, "We sent a ", length, "-digit code to", /* @__PURE__ */ import_react.default.createElement("br", null), /* @__PURE__ */ import_react.default.createElement("strong", { style: { color: "var(--dauth-text)" } }, email || "your email address")), error && /* @__PURE__ */ import_react.default.createElement("div", { style: { margin: "12px 0" } }, /* @__PURE__ */ import_react.default.createElement(import_ui2.Alert, { variant: "danger" }, error)), success && /* @__PURE__ */ import_react.default.createElement("div", { style: { margin: "12px 0" } }, /* @__PURE__ */ import_react.default.createElement(import_ui2.Alert, { variant: "success" }, success)), /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-otp-boxes", role: "group", "aria-label": "Verification code" }, otp.map((digit, i) => /* @__PURE__ */ import_react.default.createElement(
|
|
145
|
+
"input",
|
|
146
|
+
{
|
|
147
|
+
key: i,
|
|
148
|
+
ref: (el) => {
|
|
149
|
+
inputRefs.current[i] = el;
|
|
150
|
+
},
|
|
151
|
+
className: `dauth-otp-box ${digit ? "dauth-otp-box--filled" : ""}`,
|
|
152
|
+
type: "text",
|
|
153
|
+
inputMode: "numeric",
|
|
154
|
+
pattern: "[0-9]*",
|
|
155
|
+
maxLength: length,
|
|
156
|
+
value: digit,
|
|
157
|
+
onChange: (e) => handleInput(i, e.target.value),
|
|
158
|
+
onKeyDown: (e) => handleKeyDown(i, e),
|
|
159
|
+
onFocus: (e) => e.target.select(),
|
|
160
|
+
"aria-label": `Digit ${i + 1}`
|
|
161
|
+
}
|
|
162
|
+
))), /* @__PURE__ */ import_react.default.createElement(
|
|
163
|
+
import_ui.Button,
|
|
164
|
+
{
|
|
165
|
+
variant: "primary",
|
|
166
|
+
fullWidth: true,
|
|
167
|
+
loading,
|
|
168
|
+
onClick: handleVerify,
|
|
169
|
+
style: { marginTop: 8 }
|
|
170
|
+
},
|
|
171
|
+
"Verify email"
|
|
172
|
+
), /* @__PURE__ */ import_react.default.createElement("div", { className: "dauth-resend" }, countdown > 0 ? /* @__PURE__ */ import_react.default.createElement("span", null, "Resend code in ", /* @__PURE__ */ import_react.default.createElement("strong", { style: { color: "var(--dauth-teal)" } }, countdown, "s")) : /* @__PURE__ */ import_react.default.createElement(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
className: "dauth-link",
|
|
177
|
+
onClick: handleResend,
|
|
178
|
+
disabled: resending
|
|
179
|
+
},
|
|
180
|
+
resending ? "Sending\u2026" : "Resend code"
|
|
181
|
+
)), /* @__PURE__ */ import_react.default.createElement("p", { className: "dauth-footer-text" }, "Wrong email?", " ", /* @__PURE__ */ import_react.default.createElement("a", { href: "/auth/register", className: "dauth-link" }, "Go back"))));
|
|
182
|
+
};
|
|
183
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
184
|
+
0 && (module.exports = {
|
|
185
|
+
OTPScreen
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=OTPScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/screens/OTPScreen.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport { Button } from '@dravyn/ui';\nimport { Alert } from '@dravyn/ui';\nimport './auth.css';\n\nexport interface OTPScreenProps {\n /** Pre-fill the email (e.g. passed via query param or sessionStorage) */\n email?: string;\n redirectTo?: string;\n onSuccess?: () => void;\n logo?: React.ReactNode;\n brandName?: string;\n apiBase?: string;\n /** OTP length — default 6 */\n length?: number;\n}\n\nexport const OTPScreen: React.FC<OTPScreenProps> = ({\n email: emailProp,\n redirectTo = '/dashboard',\n onSuccess,\n logo,\n brandName = 'Dravyn',\n apiBase = process.env.NEXT_PUBLIC_AUTH_API_URL ?? 'http://localhost:3001',\n length = 6,\n}) => {\n const email = emailProp\n ?? (typeof sessionStorage !== 'undefined'\n ? sessionStorage.getItem('dravyn_pending_email') ?? ''\n : '');\n\n const [otp, setOtp] = React.useState<string[]>(Array(length).fill(''));\n const [loading, setLoading] = React.useState(false);\n const [resending, setResending] = React.useState(false);\n const [error, setError] = React.useState('');\n const [success, setSuccess] = React.useState('');\n const [countdown, setCountdown] = React.useState(60);\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n\n // Countdown timer for resend\n React.useEffect(() => {\n if (countdown <= 0) return;\n const t = setTimeout(() => setCountdown(c => c - 1), 1000);\n return () => clearTimeout(t);\n }, [countdown]);\n\n // Auto-focus first box\n React.useEffect(() => { inputRefs.current[0]?.focus(); }, []);\n\n const handleInput = (i: number, val: string) => {\n // Allow paste of full code\n if (val.length > 1) {\n const digits = val.replace(/\\D/g, '').slice(0, length).split('');\n const next = [...otp];\n digits.forEach((d, idx) => { if (idx < length) next[idx] = d; });\n setOtp(next);\n const last = Math.min(digits.length, length - 1);\n inputRefs.current[last]?.focus();\n return;\n }\n const digit = val.replace(/\\D/g, '');\n const next = [...otp];\n next[i] = digit;\n setOtp(next);\n if (digit && i < length - 1) inputRefs.current[i + 1]?.focus();\n };\n\n const handleKeyDown = (i: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Backspace' && !otp[i] && i > 0) {\n inputRefs.current[i - 1]?.focus();\n }\n };\n\n const handleVerify = async () => {\n const code = otp.join('');\n if (code.length < length) { setError('Enter the complete verification code.'); return; }\n setLoading(true);\n setError('');\n try {\n const res = await fetch(`${apiBase}/auth/verify-otp`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, otp: code }),\n });\n const data = await res.json();\n if (!res.ok) { setError(data.message ?? 'Invalid or expired code.'); return; }\n sessionStorage.removeItem('dravyn_pending_email');\n if (data.accessToken) {\n localStorage.setItem('dravyn_token', data.accessToken);\n localStorage.setItem('dravyn_user', JSON.stringify(data.user));\n }\n if (onSuccess) onSuccess();\n else window.location.href = redirectTo;\n } catch {\n setError('Unable to connect.');\n } finally {\n setLoading(false);\n }\n };\n\n const handleResend = async () => {\n setResending(true);\n setError('');\n setSuccess('');\n try {\n const res = await fetch(`${apiBase}/auth/resend-otp`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email }),\n });\n if (res.ok) {\n setSuccess('A new code has been sent to your email.');\n setCountdown(60);\n setOtp(Array(length).fill(''));\n inputRefs.current[0]?.focus();\n } else {\n setError('Could not resend. Try again shortly.');\n }\n } catch {\n setError('Unable to connect.');\n } finally {\n setResending(false);\n }\n };\n\n return (\n <div className=\"dauth-root\">\n <div className=\"dauth-card\">\n <div className=\"dauth-brand\">\n {logo ?? <div className=\"dauth-logo-default\"><span className=\"dauth-logo-dot\" />{brandName}</div>}\n </div>\n\n <div className=\"dauth-otp-icon\" aria-hidden=\"true\">✉</div>\n <h1 className=\"dauth-title\">Check your email</h1>\n <p className=\"dauth-sub\">\n We sent a {length}-digit code to<br />\n <strong style={{ color: 'var(--dauth-text)' }}>{email || 'your email address'}</strong>\n </p>\n\n {error && <div style={{ margin: '12px 0' }}><Alert variant=\"danger\">{error}</Alert></div>}\n {success && <div style={{ margin: '12px 0' }}><Alert variant=\"success\">{success}</Alert></div>}\n\n {/* OTP boxes */}\n <div className=\"dauth-otp-boxes\" role=\"group\" aria-label=\"Verification code\">\n {otp.map((digit, i) => (\n <input\n key={i}\n ref={el => { inputRefs.current[i] = el; }}\n className={`dauth-otp-box ${digit ? 'dauth-otp-box--filled' : ''}`}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n maxLength={length} // allow paste\n value={digit}\n onChange={e => handleInput(i, e.target.value)}\n onKeyDown={e => handleKeyDown(i, e)}\n onFocus={e => e.target.select()}\n aria-label={`Digit ${i + 1}`}\n />\n ))}\n </div>\n\n <Button\n variant=\"primary\"\n fullWidth\n loading={loading}\n onClick={handleVerify}\n style={{ marginTop: 8 }}\n >\n Verify email\n </Button>\n\n {/* Resend */}\n <div className=\"dauth-resend\">\n {countdown > 0 ? (\n <span>Resend code in <strong style={{ color: 'var(--dauth-teal)' }}>{countdown}s</strong></span>\n ) : (\n <button\n type=\"button\"\n className=\"dauth-link\"\n onClick={handleResend}\n disabled={resending}\n >\n {resending ? 'Sending…' : 'Resend code'}\n </button>\n )}\n </div>\n\n <p className=\"dauth-footer-text\">\n Wrong email?{' '}\n <a href=\"/auth/register\" className=\"dauth-link\">Go back</a>\n </p>\n </div>\n </div>\n );\n};\n"],"mappings":"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","names":["import_ui","React","next"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/* src/screens/auth.css */
|
|
2
|
+
.dauth-root {
|
|
3
|
+
min-height: 100vh;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
background: var(--dui-bg, #0d0d0d);
|
|
8
|
+
padding: 24px 16px;
|
|
9
|
+
font-family: var(--dui-font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
|
|
10
|
+
}
|
|
11
|
+
.dauth-card {
|
|
12
|
+
width: 100%;
|
|
13
|
+
max-width: 420px;
|
|
14
|
+
background: var(--dui-bg-raised, #161616);
|
|
15
|
+
border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));
|
|
16
|
+
border-radius: 16px;
|
|
17
|
+
padding: 36px 32px 32px;
|
|
18
|
+
animation: dauth-in 220ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
19
|
+
}
|
|
20
|
+
@keyframes dauth-in {
|
|
21
|
+
from {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
transform: translateY(10px) scale(0.98);
|
|
24
|
+
}
|
|
25
|
+
to {
|
|
26
|
+
opacity: 1;
|
|
27
|
+
transform: translateY(0) scale(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
.dauth-brand {
|
|
31
|
+
margin-bottom: 24px;
|
|
32
|
+
}
|
|
33
|
+
.dauth-logo-default {
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: 7px;
|
|
37
|
+
font-size: 15px;
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
color: var(--dui-text, #f0f0f0);
|
|
40
|
+
letter-spacing: -0.01em;
|
|
41
|
+
}
|
|
42
|
+
.dauth-logo-dot {
|
|
43
|
+
width: 8px;
|
|
44
|
+
height: 8px;
|
|
45
|
+
border-radius: 50%;
|
|
46
|
+
background: var(--dui-teal-400, #4ecdc4);
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
}
|
|
49
|
+
.dauth-title {
|
|
50
|
+
font-size: 22px;
|
|
51
|
+
font-weight: 700;
|
|
52
|
+
color: var(--dui-text, #f0f0f0);
|
|
53
|
+
letter-spacing: -0.02em;
|
|
54
|
+
line-height: 1.2;
|
|
55
|
+
margin: 0 0 6px;
|
|
56
|
+
}
|
|
57
|
+
.dauth-sub {
|
|
58
|
+
font-size: 13.5px;
|
|
59
|
+
color: var(--dui-text-muted, #888);
|
|
60
|
+
line-height: 1.55;
|
|
61
|
+
margin: 0 0 22px;
|
|
62
|
+
}
|
|
63
|
+
.dauth-fields {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
gap: 14px;
|
|
67
|
+
margin-bottom: 14px;
|
|
68
|
+
}
|
|
69
|
+
.dauth-row {
|
|
70
|
+
display: grid;
|
|
71
|
+
grid-template-columns: 1fr 1fr;
|
|
72
|
+
gap: 10px;
|
|
73
|
+
}
|
|
74
|
+
.dauth-password-wrap {
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
gap: 6px;
|
|
78
|
+
}
|
|
79
|
+
.dauth-forgot {
|
|
80
|
+
font-size: 12px;
|
|
81
|
+
color: var(--dui-text-muted, #888);
|
|
82
|
+
text-decoration: none;
|
|
83
|
+
align-self: flex-end;
|
|
84
|
+
transition: color 0.15s;
|
|
85
|
+
}
|
|
86
|
+
.dauth-forgot:hover {
|
|
87
|
+
color: var(--dui-teal-400, #4ecdc4);
|
|
88
|
+
}
|
|
89
|
+
.dauth-eye {
|
|
90
|
+
background: none;
|
|
91
|
+
border: none;
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
color: var(--dui-text-hint, #555);
|
|
94
|
+
display: inline-flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
padding: 0;
|
|
97
|
+
transition: color 0.15s;
|
|
98
|
+
}
|
|
99
|
+
.dauth-eye:hover {
|
|
100
|
+
color: var(--dui-text-muted, #888);
|
|
101
|
+
}
|
|
102
|
+
.dauth-divider {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
gap: 10px;
|
|
106
|
+
margin: 18px 0;
|
|
107
|
+
color: var(--dui-text-hint, #555);
|
|
108
|
+
font-size: 12px;
|
|
109
|
+
}
|
|
110
|
+
.dauth-divider::before,
|
|
111
|
+
.dauth-divider::after {
|
|
112
|
+
content: "";
|
|
113
|
+
flex: 1;
|
|
114
|
+
height: 0.5px;
|
|
115
|
+
background: var(--dui-border, rgba(255,255,255,0.07));
|
|
116
|
+
}
|
|
117
|
+
.dauth-google-btn {
|
|
118
|
+
width: 100%;
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
gap: 10px;
|
|
123
|
+
background: transparent;
|
|
124
|
+
border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));
|
|
125
|
+
border-radius: 8px;
|
|
126
|
+
padding: 10px 18px;
|
|
127
|
+
font-family: var(--dui-font-sans);
|
|
128
|
+
font-size: 13px;
|
|
129
|
+
font-weight: 500;
|
|
130
|
+
color: var(--dui-text, #f0f0f0);
|
|
131
|
+
cursor: pointer;
|
|
132
|
+
transition: background 0.15s, border-color 0.15s;
|
|
133
|
+
}
|
|
134
|
+
.dauth-google-btn:hover:not(:disabled) {
|
|
135
|
+
background: var(--dui-bg-overlay, #1e1e1e);
|
|
136
|
+
border-color: rgba(255, 255, 255, 0.24);
|
|
137
|
+
}
|
|
138
|
+
.dauth-google-btn:disabled {
|
|
139
|
+
opacity: 0.4;
|
|
140
|
+
cursor: not-allowed;
|
|
141
|
+
}
|
|
142
|
+
.dauth-otp-icon {
|
|
143
|
+
font-size: 28px;
|
|
144
|
+
margin-bottom: 12px;
|
|
145
|
+
color: var(--dui-teal-400, #4ecdc4);
|
|
146
|
+
}
|
|
147
|
+
.dauth-otp-boxes {
|
|
148
|
+
display: flex;
|
|
149
|
+
gap: 8px;
|
|
150
|
+
justify-content: center;
|
|
151
|
+
margin: 20px 0 8px;
|
|
152
|
+
}
|
|
153
|
+
.dauth-otp-box {
|
|
154
|
+
width: 46px;
|
|
155
|
+
height: 54px;
|
|
156
|
+
background: var(--dui-bg, #0d0d0d);
|
|
157
|
+
border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));
|
|
158
|
+
border-radius: 8px;
|
|
159
|
+
color: var(--dui-text, #f0f0f0);
|
|
160
|
+
font-size: 22px;
|
|
161
|
+
font-weight: 700;
|
|
162
|
+
font-family: var(--dui-font-sans);
|
|
163
|
+
text-align: center;
|
|
164
|
+
outline: none;
|
|
165
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
166
|
+
caret-color: var(--dui-teal-400, #4ecdc4);
|
|
167
|
+
}
|
|
168
|
+
.dauth-otp-box:focus {
|
|
169
|
+
border-color: var(--dui-teal-400, #4ecdc4);
|
|
170
|
+
box-shadow: 0 0 0 3px rgba(78, 205, 196, 0.12);
|
|
171
|
+
}
|
|
172
|
+
.dauth-otp-box--filled {
|
|
173
|
+
border-color: var(--dui-teal-400, #4ecdc4);
|
|
174
|
+
background: rgba(78, 205, 196, 0.04);
|
|
175
|
+
}
|
|
176
|
+
.dauth-resend {
|
|
177
|
+
text-align: center;
|
|
178
|
+
font-size: 13px;
|
|
179
|
+
color: var(--dui-text-muted, #888);
|
|
180
|
+
margin: 14px 0 4px;
|
|
181
|
+
}
|
|
182
|
+
.dauth-link {
|
|
183
|
+
color: var(--dui-teal-400, #4ecdc4);
|
|
184
|
+
text-decoration: none;
|
|
185
|
+
font-weight: 500;
|
|
186
|
+
background: none;
|
|
187
|
+
border: none;
|
|
188
|
+
cursor: pointer;
|
|
189
|
+
font-size: inherit;
|
|
190
|
+
font-family: inherit;
|
|
191
|
+
padding: 0;
|
|
192
|
+
transition: opacity 0.15s;
|
|
193
|
+
}
|
|
194
|
+
.dauth-link:hover {
|
|
195
|
+
opacity: 0.8;
|
|
196
|
+
}
|
|
197
|
+
.dauth-footer-text {
|
|
198
|
+
text-align: center;
|
|
199
|
+
font-size: 13px;
|
|
200
|
+
color: var(--dui-text-muted, #888);
|
|
201
|
+
margin-top: 18px;
|
|
202
|
+
}
|
|
203
|
+
.dauth-terms {
|
|
204
|
+
text-align: center;
|
|
205
|
+
font-size: 11.5px;
|
|
206
|
+
color: var(--dui-text-hint, #555);
|
|
207
|
+
margin-top: 12px;
|
|
208
|
+
line-height: 1.6;
|
|
209
|
+
}
|
|
210
|
+
:root {
|
|
211
|
+
--dauth-text: var(--dui-text, #f0f0f0);
|
|
212
|
+
--dauth-muted: var(--dui-text-muted, #888888);
|
|
213
|
+
--dauth-teal: var(--dui-teal-400, #4ecdc4);
|
|
214
|
+
--dauth-green: #22c55e;
|
|
215
|
+
--dauth-label: var(--dui-text-muted, #888888);
|
|
216
|
+
}
|
|
217
|
+
.dauth-label {
|
|
218
|
+
font-size: 12px;
|
|
219
|
+
font-weight: 500;
|
|
220
|
+
color: var(--dauth-label);
|
|
221
|
+
}
|
|
222
|
+
@media (max-width: 480px) {
|
|
223
|
+
.dauth-card {
|
|
224
|
+
padding: 28px 20px 24px;
|
|
225
|
+
}
|
|
226
|
+
.dauth-row {
|
|
227
|
+
grid-template-columns: 1fr;
|
|
228
|
+
}
|
|
229
|
+
.dauth-otp-box {
|
|
230
|
+
width: 40px;
|
|
231
|
+
height: 48px;
|
|
232
|
+
font-size: 20px;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/*# sourceMappingURL=RegisterScreen.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/screens/auth.css"],"sourcesContent":["/*\n Dravyn Auth UI — Styles\n Consumes @dravyn/ui CSS custom properties.\n Import tokens first: import 'dravyn-ui/tokens'\n Then import this file once: import '@dravyn/auth-ui/auth.css'\n*/\n\n/* ── Root / centred layout ──────────────────────────────────────────────── */\n.dauth-root {\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dui-bg, #0d0d0d);\n padding: 24px 16px;\n font-family: var(--dui-font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);\n}\n\n/* ── Card ───────────────────────────────────────────────────────────────── */\n.dauth-card {\n width: 100%;\n max-width: 420px;\n background: var(--dui-bg-raised, #161616);\n border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));\n border-radius: 16px;\n padding: 36px 32px 32px;\n animation: dauth-in 220ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n@keyframes dauth-in {\n from { opacity: 0; transform: translateY(10px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n}\n\n/* ── Brand / logo ───────────────────────────────────────────────────────── */\n.dauth-brand {\n margin-bottom: 24px;\n}\n\n.dauth-logo-default {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 15px;\n font-weight: 700;\n color: var(--dui-text, #f0f0f0);\n letter-spacing: -0.01em;\n}\n\n.dauth-logo-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--dui-teal-400, #4ecdc4);\n flex-shrink: 0;\n}\n\n/* ── Headings ────────────────────────────────────────────────────────────── */\n.dauth-title {\n font-size: 22px;\n font-weight: 700;\n color: var(--dui-text, #f0f0f0);\n letter-spacing: -0.02em;\n line-height: 1.2;\n margin: 0 0 6px;\n}\n\n.dauth-sub {\n font-size: 13.5px;\n color: var(--dui-text-muted, #888);\n line-height: 1.55;\n margin: 0 0 22px;\n}\n\n/* ── Form fields ─────────────────────────────────────────────────────────── */\n.dauth-fields {\n display: flex;\n flex-direction: column;\n gap: 14px;\n margin-bottom: 14px;\n}\n\n.dauth-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n\n/* ── Password wrap (holds input + forgot link) ───────────────────────────── */\n.dauth-password-wrap {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.dauth-forgot {\n font-size: 12px;\n color: var(--dui-text-muted, #888);\n text-decoration: none;\n align-self: flex-end;\n transition: color 0.15s;\n}\n\n.dauth-forgot:hover { color: var(--dui-teal-400, #4ecdc4); }\n\n/* ── Show/hide password button ───────────────────────────────────────────── */\n.dauth-eye {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--dui-text-hint, #555);\n display: inline-flex;\n align-items: center;\n padding: 0;\n transition: color 0.15s;\n}\n.dauth-eye:hover { color: var(--dui-text-muted, #888); }\n\n/* ── Divider ─────────────────────────────────────────────────────────────── */\n.dauth-divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 18px 0;\n color: var(--dui-text-hint, #555);\n font-size: 12px;\n}\n.dauth-divider::before,\n.dauth-divider::after {\n content: '';\n flex: 1;\n height: 0.5px;\n background: var(--dui-border, rgba(255,255,255,0.07));\n}\n\n/* ── Google OAuth button ─────────────────────────────────────────────────── */\n.dauth-google-btn {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n background: transparent;\n border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));\n border-radius: 8px;\n padding: 10px 18px;\n font-family: var(--dui-font-sans);\n font-size: 13px;\n font-weight: 500;\n color: var(--dui-text, #f0f0f0);\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n}\n.dauth-google-btn:hover:not(:disabled) {\n background: var(--dui-bg-overlay, #1e1e1e);\n border-color: rgba(255,255,255,0.24);\n}\n.dauth-google-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n\n/* ── OTP boxes ───────────────────────────────────────────────────────────── */\n.dauth-otp-icon {\n font-size: 28px;\n margin-bottom: 12px;\n color: var(--dui-teal-400, #4ecdc4);\n}\n\n.dauth-otp-boxes {\n display: flex;\n gap: 8px;\n justify-content: center;\n margin: 20px 0 8px;\n}\n\n.dauth-otp-box {\n width: 46px;\n height: 54px;\n background: var(--dui-bg, #0d0d0d);\n border: 0.5px solid var(--dui-border-strong, rgba(255,255,255,0.16));\n border-radius: 8px;\n color: var(--dui-text, #f0f0f0);\n font-size: 22px;\n font-weight: 700;\n font-family: var(--dui-font-sans);\n text-align: center;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n caret-color: var(--dui-teal-400, #4ecdc4);\n}\n\n.dauth-otp-box:focus {\n border-color: var(--dui-teal-400, #4ecdc4);\n box-shadow: 0 0 0 3px rgba(78, 205, 196, 0.12);\n}\n\n.dauth-otp-box--filled {\n border-color: var(--dui-teal-400, #4ecdc4);\n background: rgba(78, 205, 196, 0.04);\n}\n\n/* ── Resend row ──────────────────────────────────────────────────────────── */\n.dauth-resend {\n text-align: center;\n font-size: 13px;\n color: var(--dui-text-muted, #888);\n margin: 14px 0 4px;\n}\n\n/* ── Links ───────────────────────────────────────────────────────────────── */\n.dauth-link {\n color: var(--dui-teal-400, #4ecdc4);\n text-decoration: none;\n font-weight: 500;\n background: none;\n border: none;\n cursor: pointer;\n font-size: inherit;\n font-family: inherit;\n padding: 0;\n transition: opacity 0.15s;\n}\n.dauth-link:hover { opacity: 0.8; }\n\n/* ── Footer text + terms ─────────────────────────────────────────────────── */\n.dauth-footer-text {\n text-align: center;\n font-size: 13px;\n color: var(--dui-text-muted, #888);\n margin-top: 18px;\n}\n\n.dauth-terms {\n text-align: center;\n font-size: 11.5px;\n color: var(--dui-text-hint, #555);\n margin-top: 12px;\n line-height: 1.6;\n}\n\n/* ── CSS variable aliases (readable names inside auth components) ─────────── */\n:root {\n --dauth-text: var(--dui-text, #f0f0f0);\n --dauth-muted: var(--dui-text-muted, #888888);\n --dauth-teal: var(--dui-teal-400, #4ecdc4);\n --dauth-green: #22c55e;\n --dauth-label: var(--dui-text-muted, #888888);\n}\n\n/* ── Label helper (used in ResetPasswordScreen) ───────────────────────────── */\n.dauth-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--dauth-label);\n}\n\n/* ── Responsive ──────────────────────────────────────────────────────────── */\n@media (max-width: 480px) {\n .dauth-card { padding: 28px 20px 24px; }\n .dauth-row { grid-template-columns: 1fr; }\n .dauth-otp-box { width: 40px; height: 48px; font-size: 20px; }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface RegisterScreenProps {
|
|
4
|
+
redirectTo?: string;
|
|
5
|
+
onSuccess?: (token: string, user: AuthUser) => void;
|
|
6
|
+
logo?: React.ReactNode;
|
|
7
|
+
brandName?: string;
|
|
8
|
+
apiBase?: string;
|
|
9
|
+
/** Extra fields to collect — rendered after the core fields */
|
|
10
|
+
extraFields?: React.ReactNode;
|
|
11
|
+
/** If true, redirect to OTP screen after register instead of auto-login */
|
|
12
|
+
requireOTP?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface AuthUser {
|
|
15
|
+
id: string;
|
|
16
|
+
email: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
declare const RegisterScreen: React.FC<RegisterScreenProps>;
|
|
20
|
+
|
|
21
|
+
export { RegisterScreen, type RegisterScreenProps };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface RegisterScreenProps {
|
|
4
|
+
redirectTo?: string;
|
|
5
|
+
onSuccess?: (token: string, user: AuthUser) => void;
|
|
6
|
+
logo?: React.ReactNode;
|
|
7
|
+
brandName?: string;
|
|
8
|
+
apiBase?: string;
|
|
9
|
+
/** Extra fields to collect — rendered after the core fields */
|
|
10
|
+
extraFields?: React.ReactNode;
|
|
11
|
+
/** If true, redirect to OTP screen after register instead of auto-login */
|
|
12
|
+
requireOTP?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface AuthUser {
|
|
15
|
+
id: string;
|
|
16
|
+
email: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
declare const RegisterScreen: React.FC<RegisterScreenProps>;
|
|
20
|
+
|
|
21
|
+
export { RegisterScreen, type RegisterScreenProps };
|