@xouteiro/auth_npm 1.0.5 → 1.0.7
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/README.md +2 -0
- package/dist/index.js +221 -64
- package/dist/index.mjs +216 -63
- package/package.json +1 -1
- package/src/components/LoginOnly.jsx +33 -0
- package/src/components/LoginRegisterFlow.jsx +77 -0
- package/src/components/LogoutButton.jsx +18 -0
- package/src/components/RegisterOnly.jsx +47 -0
- package/src/index.js +8 -3
- package/src/logout.js +18 -0
- package/src/register.js +29 -0
- package/src/AuthWrapper.jsx +0 -39
- package/src/LogoutButton.jsx +0 -12
package/README.md
ADDED
package/dist/index.js
CHANGED
@@ -1361,7 +1361,7 @@ var require_react_development = __commonJS({
|
|
1361
1361
|
}
|
1362
1362
|
return dispatcher.useContext(Context);
|
1363
1363
|
}
|
1364
|
-
function
|
1364
|
+
function useState6(initialState) {
|
1365
1365
|
var dispatcher = resolveDispatcher();
|
1366
1366
|
return dispatcher.useState(initialState);
|
1367
1367
|
}
|
@@ -1373,7 +1373,7 @@ var require_react_development = __commonJS({
|
|
1373
1373
|
var dispatcher = resolveDispatcher();
|
1374
1374
|
return dispatcher.useRef(initialValue);
|
1375
1375
|
}
|
1376
|
-
function
|
1376
|
+
function useEffect2(create, deps) {
|
1377
1377
|
var dispatcher = resolveDispatcher();
|
1378
1378
|
return dispatcher.useEffect(create, deps);
|
1379
1379
|
}
|
@@ -2156,7 +2156,7 @@ var require_react_development = __commonJS({
|
|
2156
2156
|
exports2.useContext = useContext;
|
2157
2157
|
exports2.useDebugValue = useDebugValue;
|
2158
2158
|
exports2.useDeferredValue = useDeferredValue;
|
2159
|
-
exports2.useEffect =
|
2159
|
+
exports2.useEffect = useEffect2;
|
2160
2160
|
exports2.useId = useId;
|
2161
2161
|
exports2.useImperativeHandle = useImperativeHandle;
|
2162
2162
|
exports2.useInsertionEffect = useInsertionEffect;
|
@@ -2164,7 +2164,7 @@ var require_react_development = __commonJS({
|
|
2164
2164
|
exports2.useMemo = useMemo;
|
2165
2165
|
exports2.useReducer = useReducer;
|
2166
2166
|
exports2.useRef = useRef;
|
2167
|
-
exports2.useState =
|
2167
|
+
exports2.useState = useState6;
|
2168
2168
|
exports2.useSyncExternalStore = useSyncExternalStore;
|
2169
2169
|
exports2.useTransition = useTransition;
|
2170
2170
|
exports2.version = ReactVersion;
|
@@ -2191,67 +2191,25 @@ var require_react = __commonJS({
|
|
2191
2191
|
// src/index.js
|
2192
2192
|
var index_exports = {};
|
2193
2193
|
__export(index_exports, {
|
2194
|
-
|
2194
|
+
LoginOnly: () => LoginOnly,
|
2195
|
+
LoginRegisterFlow: () => LoginRegisterFlow,
|
2195
2196
|
LogoutButton: () => LogoutButton,
|
2197
|
+
RegisterOnly: () => RegisterOnly,
|
2196
2198
|
initializeSupabase: () => initializeSupabase,
|
2197
2199
|
isAdmin: () => isAdmin,
|
2200
|
+
logout: () => logout,
|
2201
|
+
registerWithEmail: () => registerWithEmail,
|
2198
2202
|
signInWithEmail: () => signInWithEmail,
|
2199
2203
|
supabase: () => supabase,
|
2200
2204
|
useAuth: () => useAuth
|
2201
2205
|
});
|
2202
2206
|
module.exports = __toCommonJS(index_exports);
|
2203
2207
|
|
2204
|
-
// src/
|
2208
|
+
// src/useAuth.js
|
2205
2209
|
var import_react = __toESM(require_react());
|
2206
|
-
|
2207
|
-
var import_auth_ui_shared = require("@supabase/auth-ui-shared");
|
2208
|
-
|
2209
|
-
// src/supabaseClient.js
|
2210
|
-
var import_supabase_js = require("@supabase/supabase-js");
|
2211
|
-
var supabase = null;
|
2212
|
-
function initializeSupabase(url, anonKey) {
|
2213
|
-
if (!url || !anonKey) {
|
2214
|
-
throw new Error("Supabase URL and Anon Key are required to initialize the client.");
|
2215
|
-
}
|
2216
|
-
supabase = (0, import_supabase_js.createClient)(url, anonKey);
|
2217
|
-
}
|
2218
|
-
|
2219
|
-
// src/AuthWrapper.jsx
|
2220
|
-
function AuthWrapper({ onAuth, providers = ["google", "github"], theme = "dark" }) {
|
2221
|
-
if (!supabase) {
|
2222
|
-
throw new Error("Supabase client is not initialized. Call initializeSupabase() before using AuthWrapper.");
|
2223
|
-
}
|
2210
|
+
function useAuth(supabaseClient) {
|
2224
2211
|
const [session, setSession] = (0, import_react.useState)(null);
|
2225
2212
|
(0, import_react.useEffect)(() => {
|
2226
|
-
supabase.auth.getSession().then(({ data: { session: session2 } }) => {
|
2227
|
-
setSession(session2);
|
2228
|
-
if (session2) onAuth == null ? void 0 : onAuth(session2);
|
2229
|
-
});
|
2230
|
-
const { data: subscription } = supabase.auth.onAuthStateChange((_event, session2) => {
|
2231
|
-
setSession(session2);
|
2232
|
-
if (session2) onAuth == null ? void 0 : onAuth(session2);
|
2233
|
-
});
|
2234
|
-
return () => subscription == null ? void 0 : subscription.unsubscribe();
|
2235
|
-
}, [onAuth]);
|
2236
|
-
if (!session) {
|
2237
|
-
return /* @__PURE__ */ React.createElement(
|
2238
|
-
import_auth_ui_react.Auth,
|
2239
|
-
{
|
2240
|
-
supabaseClient: supabase,
|
2241
|
-
appearance: { theme: import_auth_ui_shared.ThemeSupa },
|
2242
|
-
providers,
|
2243
|
-
theme
|
2244
|
-
}
|
2245
|
-
);
|
2246
|
-
}
|
2247
|
-
return /* @__PURE__ */ React.createElement("div", null, "\u2705 Logged in as: ", session.user.email);
|
2248
|
-
}
|
2249
|
-
|
2250
|
-
// src/useAuth.js
|
2251
|
-
var import_react2 = __toESM(require_react());
|
2252
|
-
function useAuth(supabaseClient) {
|
2253
|
-
const [session, setSession] = (0, import_react2.useState)(null);
|
2254
|
-
(0, import_react2.useEffect)(() => {
|
2255
2213
|
supabaseClient.auth.getSession().then(({ data: { session: session2 } }) => {
|
2256
2214
|
setSession(session2);
|
2257
2215
|
});
|
@@ -2267,21 +2225,21 @@ function useAuth(supabaseClient) {
|
|
2267
2225
|
return { session, signOut };
|
2268
2226
|
}
|
2269
2227
|
|
2270
|
-
// src/LogoutButton.jsx
|
2271
|
-
function LogoutButton({ supabaseClient, onLogout }) {
|
2272
|
-
const { signOut } = useAuth(supabaseClient);
|
2273
|
-
const handleLogout = async () => {
|
2274
|
-
await signOut();
|
2275
|
-
onLogout == null ? void 0 : onLogout();
|
2276
|
-
};
|
2277
|
-
return /* @__PURE__ */ React.createElement("button", { onClick: handleLogout }, "\u{1F6AA} Log out");
|
2278
|
-
}
|
2279
|
-
|
2280
2228
|
// src/utils.js
|
2281
2229
|
function isAdmin(user) {
|
2282
2230
|
return (user == null ? void 0 : user.role) === "admin";
|
2283
2231
|
}
|
2284
2232
|
|
2233
|
+
// src/supabaseClient.js
|
2234
|
+
var import_supabase_js = require("@supabase/supabase-js");
|
2235
|
+
var supabase = null;
|
2236
|
+
function initializeSupabase(url, anonKey) {
|
2237
|
+
if (!url || !anonKey) {
|
2238
|
+
throw new Error("Supabase URL and Anon Key are required to initialize the client.");
|
2239
|
+
}
|
2240
|
+
supabase = (0, import_supabase_js.createClient)(url, anonKey);
|
2241
|
+
}
|
2242
|
+
|
2285
2243
|
// src/login.js
|
2286
2244
|
async function signInWithEmail(email, password) {
|
2287
2245
|
try {
|
@@ -2295,12 +2253,211 @@ async function signInWithEmail(email, password) {
|
|
2295
2253
|
return { session: null, error: err };
|
2296
2254
|
}
|
2297
2255
|
}
|
2256
|
+
|
2257
|
+
// src/register.js
|
2258
|
+
async function registerWithEmail(email, password, username, phone) {
|
2259
|
+
try {
|
2260
|
+
const { data: user, error } = await supabase.auth.signUp({
|
2261
|
+
email,
|
2262
|
+
password,
|
2263
|
+
options: {
|
2264
|
+
data: {
|
2265
|
+
username,
|
2266
|
+
// Store the display name
|
2267
|
+
phone
|
2268
|
+
// Store the phone number
|
2269
|
+
}
|
2270
|
+
}
|
2271
|
+
});
|
2272
|
+
return { user, error };
|
2273
|
+
} catch (err) {
|
2274
|
+
console.error("Unexpected error during registration:", err);
|
2275
|
+
return { user: null, error: err };
|
2276
|
+
}
|
2277
|
+
}
|
2278
|
+
|
2279
|
+
// src/logout.js
|
2280
|
+
async function logout() {
|
2281
|
+
try {
|
2282
|
+
const { error } = await supabase.auth.signOut();
|
2283
|
+
if (error) {
|
2284
|
+
console.error("Error during logout:", error);
|
2285
|
+
}
|
2286
|
+
return { error };
|
2287
|
+
} catch (err) {
|
2288
|
+
console.error("Unexpected error during logout:", err);
|
2289
|
+
return { error: err };
|
2290
|
+
}
|
2291
|
+
}
|
2292
|
+
|
2293
|
+
// src/components/LoginRegisterFlow.jsx
|
2294
|
+
var import_react2 = __toESM(require_react());
|
2295
|
+
function LoginRegisterFlow() {
|
2296
|
+
const [mode, setMode] = (0, import_react2.useState)("login");
|
2297
|
+
const [identifier, setIdentifier] = (0, import_react2.useState)("");
|
2298
|
+
const [password, setPassword] = (0, import_react2.useState)("");
|
2299
|
+
const [username, setUsername] = (0, import_react2.useState)("");
|
2300
|
+
const [phone, setPhone] = (0, import_react2.useState)("");
|
2301
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
2302
|
+
const handleLogin = async (e) => {
|
2303
|
+
e.preventDefault();
|
2304
|
+
const { error: error2 } = await signInWithEmail(identifier, password);
|
2305
|
+
setError(error2 ? error2.message : null);
|
2306
|
+
};
|
2307
|
+
const handleRegister = async (e) => {
|
2308
|
+
e.preventDefault();
|
2309
|
+
const { error: error2 } = await registerWithEmail(identifier, password, username, phone);
|
2310
|
+
setError(error2 ? error2.message : null);
|
2311
|
+
};
|
2312
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", null, /* @__PURE__ */ import_react2.default.createElement("button", { onClick: () => setMode("login") }, "Login"), /* @__PURE__ */ import_react2.default.createElement("button", { onClick: () => setMode("register") }, "Register"), mode === "login" ? /* @__PURE__ */ import_react2.default.createElement("form", { onSubmit: handleLogin }, /* @__PURE__ */ import_react2.default.createElement(
|
2313
|
+
"input",
|
2314
|
+
{
|
2315
|
+
type: "text",
|
2316
|
+
placeholder: "Email, phone, or username",
|
2317
|
+
value: identifier,
|
2318
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2319
|
+
}
|
2320
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2321
|
+
"input",
|
2322
|
+
{
|
2323
|
+
type: "password",
|
2324
|
+
placeholder: "Password",
|
2325
|
+
value: password,
|
2326
|
+
onChange: (e) => setPassword(e.target.value)
|
2327
|
+
}
|
2328
|
+
), /* @__PURE__ */ import_react2.default.createElement("button", { type: "submit" }, "Login")) : /* @__PURE__ */ import_react2.default.createElement("form", { onSubmit: handleRegister }, /* @__PURE__ */ import_react2.default.createElement(
|
2329
|
+
"input",
|
2330
|
+
{
|
2331
|
+
type: "text",
|
2332
|
+
placeholder: "Email",
|
2333
|
+
value: identifier,
|
2334
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2335
|
+
}
|
2336
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2337
|
+
"input",
|
2338
|
+
{
|
2339
|
+
type: "password",
|
2340
|
+
placeholder: "Password",
|
2341
|
+
value: password,
|
2342
|
+
onChange: (e) => setPassword(e.target.value)
|
2343
|
+
}
|
2344
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2345
|
+
"input",
|
2346
|
+
{
|
2347
|
+
type: "text",
|
2348
|
+
placeholder: "Username (optional)",
|
2349
|
+
value: username,
|
2350
|
+
onChange: (e) => setUsername(e.target.value)
|
2351
|
+
}
|
2352
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2353
|
+
"input",
|
2354
|
+
{
|
2355
|
+
type: "text",
|
2356
|
+
placeholder: "Phone (optional)",
|
2357
|
+
value: phone,
|
2358
|
+
onChange: (e) => setPhone(e.target.value)
|
2359
|
+
}
|
2360
|
+
), /* @__PURE__ */ import_react2.default.createElement("button", { type: "submit" }, "Register")), error && /* @__PURE__ */ import_react2.default.createElement("div", { style: { color: "red" } }, error));
|
2361
|
+
}
|
2362
|
+
|
2363
|
+
// src/components/LoginOnly.jsx
|
2364
|
+
var import_react3 = __toESM(require_react());
|
2365
|
+
function LoginOnly() {
|
2366
|
+
const [identifier, setIdentifier] = (0, import_react3.useState)("");
|
2367
|
+
const [password, setPassword] = (0, import_react3.useState)("");
|
2368
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
2369
|
+
const handleLogin = async (e) => {
|
2370
|
+
e.preventDefault();
|
2371
|
+
const { error: error2 } = await signInWithEmail(identifier, password);
|
2372
|
+
setError(error2 ? error2.message : null);
|
2373
|
+
};
|
2374
|
+
return /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handleLogin }, /* @__PURE__ */ import_react3.default.createElement(
|
2375
|
+
"input",
|
2376
|
+
{
|
2377
|
+
type: "text",
|
2378
|
+
placeholder: "Email, phone, or username",
|
2379
|
+
value: identifier,
|
2380
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2381
|
+
}
|
2382
|
+
), /* @__PURE__ */ import_react3.default.createElement(
|
2383
|
+
"input",
|
2384
|
+
{
|
2385
|
+
type: "password",
|
2386
|
+
placeholder: "Password",
|
2387
|
+
value: password,
|
2388
|
+
onChange: (e) => setPassword(e.target.value)
|
2389
|
+
}
|
2390
|
+
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit" }, "Login"), error && /* @__PURE__ */ import_react3.default.createElement("div", { style: { color: "red" } }, error));
|
2391
|
+
}
|
2392
|
+
|
2393
|
+
// src/components/RegisterOnly.jsx
|
2394
|
+
var import_react4 = __toESM(require_react());
|
2395
|
+
function RegisterOnly() {
|
2396
|
+
const [email, setEmail] = (0, import_react4.useState)("");
|
2397
|
+
const [password, setPassword] = (0, import_react4.useState)("");
|
2398
|
+
const [username, setUsername] = (0, import_react4.useState)("");
|
2399
|
+
const [phone, setPhone] = (0, import_react4.useState)("");
|
2400
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
2401
|
+
const handleRegister = async (e) => {
|
2402
|
+
e.preventDefault();
|
2403
|
+
const { error: error2 } = await registerWithEmail(email, password, username, phone);
|
2404
|
+
setError(error2 ? error2.message : null);
|
2405
|
+
};
|
2406
|
+
return /* @__PURE__ */ import_react4.default.createElement("form", { onSubmit: handleRegister }, /* @__PURE__ */ import_react4.default.createElement(
|
2407
|
+
"input",
|
2408
|
+
{
|
2409
|
+
type: "text",
|
2410
|
+
placeholder: "Email",
|
2411
|
+
value: email,
|
2412
|
+
onChange: (e) => setEmail(e.target.value)
|
2413
|
+
}
|
2414
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2415
|
+
"input",
|
2416
|
+
{
|
2417
|
+
type: "password",
|
2418
|
+
placeholder: "Password",
|
2419
|
+
value: password,
|
2420
|
+
onChange: (e) => setPassword(e.target.value)
|
2421
|
+
}
|
2422
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2423
|
+
"input",
|
2424
|
+
{
|
2425
|
+
type: "text",
|
2426
|
+
placeholder: "Username (optional)",
|
2427
|
+
value: username,
|
2428
|
+
onChange: (e) => setUsername(e.target.value)
|
2429
|
+
}
|
2430
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2431
|
+
"input",
|
2432
|
+
{
|
2433
|
+
type: "text",
|
2434
|
+
placeholder: "Phone (optional)",
|
2435
|
+
value: phone,
|
2436
|
+
onChange: (e) => setPhone(e.target.value)
|
2437
|
+
}
|
2438
|
+
), /* @__PURE__ */ import_react4.default.createElement("button", { type: "submit" }, "Register"), error && /* @__PURE__ */ import_react4.default.createElement("div", { style: { color: "red" } }, error));
|
2439
|
+
}
|
2440
|
+
|
2441
|
+
// src/components/LogoutButton.jsx
|
2442
|
+
var import_react5 = __toESM(require_react());
|
2443
|
+
function LogoutButton() {
|
2444
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
2445
|
+
const handleLogout = async () => {
|
2446
|
+
const { error: error2 } = await logout();
|
2447
|
+
setError(error2 ? error2.message : null);
|
2448
|
+
};
|
2449
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("button", { onClick: handleLogout }, "Logout"), error && /* @__PURE__ */ import_react5.default.createElement("div", { style: { color: "red" } }, error));
|
2450
|
+
}
|
2298
2451
|
// Annotate the CommonJS export names for ESM import in node:
|
2299
2452
|
0 && (module.exports = {
|
2300
|
-
|
2453
|
+
LoginOnly,
|
2454
|
+
LoginRegisterFlow,
|
2301
2455
|
LogoutButton,
|
2456
|
+
RegisterOnly,
|
2302
2457
|
initializeSupabase,
|
2303
2458
|
isAdmin,
|
2459
|
+
logout,
|
2460
|
+
registerWithEmail,
|
2304
2461
|
signInWithEmail,
|
2305
2462
|
supabase,
|
2306
2463
|
useAuth
|
package/dist/index.mjs
CHANGED
@@ -1356,7 +1356,7 @@ var require_react_development = __commonJS({
|
|
1356
1356
|
}
|
1357
1357
|
return dispatcher.useContext(Context);
|
1358
1358
|
}
|
1359
|
-
function
|
1359
|
+
function useState6(initialState) {
|
1360
1360
|
var dispatcher = resolveDispatcher();
|
1361
1361
|
return dispatcher.useState(initialState);
|
1362
1362
|
}
|
@@ -1368,7 +1368,7 @@ var require_react_development = __commonJS({
|
|
1368
1368
|
var dispatcher = resolveDispatcher();
|
1369
1369
|
return dispatcher.useRef(initialValue);
|
1370
1370
|
}
|
1371
|
-
function
|
1371
|
+
function useEffect2(create, deps) {
|
1372
1372
|
var dispatcher = resolveDispatcher();
|
1373
1373
|
return dispatcher.useEffect(create, deps);
|
1374
1374
|
}
|
@@ -2151,7 +2151,7 @@ var require_react_development = __commonJS({
|
|
2151
2151
|
exports.useContext = useContext;
|
2152
2152
|
exports.useDebugValue = useDebugValue;
|
2153
2153
|
exports.useDeferredValue = useDeferredValue;
|
2154
|
-
exports.useEffect =
|
2154
|
+
exports.useEffect = useEffect2;
|
2155
2155
|
exports.useId = useId;
|
2156
2156
|
exports.useImperativeHandle = useImperativeHandle;
|
2157
2157
|
exports.useInsertionEffect = useInsertionEffect;
|
@@ -2159,7 +2159,7 @@ var require_react_development = __commonJS({
|
|
2159
2159
|
exports.useMemo = useMemo;
|
2160
2160
|
exports.useReducer = useReducer;
|
2161
2161
|
exports.useRef = useRef;
|
2162
|
-
exports.useState =
|
2162
|
+
exports.useState = useState6;
|
2163
2163
|
exports.useSyncExternalStore = useSyncExternalStore;
|
2164
2164
|
exports.useTransition = useTransition;
|
2165
2165
|
exports.version = ReactVersion;
|
@@ -2183,57 +2183,11 @@ var require_react = __commonJS({
|
|
2183
2183
|
}
|
2184
2184
|
});
|
2185
2185
|
|
2186
|
-
// src/
|
2186
|
+
// src/useAuth.js
|
2187
2187
|
var import_react = __toESM(require_react());
|
2188
|
-
|
2189
|
-
import { ThemeSupa } from "@supabase/auth-ui-shared";
|
2190
|
-
|
2191
|
-
// src/supabaseClient.js
|
2192
|
-
import { createClient } from "@supabase/supabase-js";
|
2193
|
-
var supabase = null;
|
2194
|
-
function initializeSupabase(url, anonKey) {
|
2195
|
-
if (!url || !anonKey) {
|
2196
|
-
throw new Error("Supabase URL and Anon Key are required to initialize the client.");
|
2197
|
-
}
|
2198
|
-
supabase = createClient(url, anonKey);
|
2199
|
-
}
|
2200
|
-
|
2201
|
-
// src/AuthWrapper.jsx
|
2202
|
-
function AuthWrapper({ onAuth, providers = ["google", "github"], theme = "dark" }) {
|
2203
|
-
if (!supabase) {
|
2204
|
-
throw new Error("Supabase client is not initialized. Call initializeSupabase() before using AuthWrapper.");
|
2205
|
-
}
|
2188
|
+
function useAuth(supabaseClient) {
|
2206
2189
|
const [session, setSession] = (0, import_react.useState)(null);
|
2207
2190
|
(0, import_react.useEffect)(() => {
|
2208
|
-
supabase.auth.getSession().then(({ data: { session: session2 } }) => {
|
2209
|
-
setSession(session2);
|
2210
|
-
if (session2) onAuth == null ? void 0 : onAuth(session2);
|
2211
|
-
});
|
2212
|
-
const { data: subscription } = supabase.auth.onAuthStateChange((_event, session2) => {
|
2213
|
-
setSession(session2);
|
2214
|
-
if (session2) onAuth == null ? void 0 : onAuth(session2);
|
2215
|
-
});
|
2216
|
-
return () => subscription == null ? void 0 : subscription.unsubscribe();
|
2217
|
-
}, [onAuth]);
|
2218
|
-
if (!session) {
|
2219
|
-
return /* @__PURE__ */ React.createElement(
|
2220
|
-
Auth,
|
2221
|
-
{
|
2222
|
-
supabaseClient: supabase,
|
2223
|
-
appearance: { theme: ThemeSupa },
|
2224
|
-
providers,
|
2225
|
-
theme
|
2226
|
-
}
|
2227
|
-
);
|
2228
|
-
}
|
2229
|
-
return /* @__PURE__ */ React.createElement("div", null, "\u2705 Logged in as: ", session.user.email);
|
2230
|
-
}
|
2231
|
-
|
2232
|
-
// src/useAuth.js
|
2233
|
-
var import_react2 = __toESM(require_react());
|
2234
|
-
function useAuth(supabaseClient) {
|
2235
|
-
const [session, setSession] = (0, import_react2.useState)(null);
|
2236
|
-
(0, import_react2.useEffect)(() => {
|
2237
2191
|
supabaseClient.auth.getSession().then(({ data: { session: session2 } }) => {
|
2238
2192
|
setSession(session2);
|
2239
2193
|
});
|
@@ -2249,21 +2203,21 @@ function useAuth(supabaseClient) {
|
|
2249
2203
|
return { session, signOut };
|
2250
2204
|
}
|
2251
2205
|
|
2252
|
-
// src/LogoutButton.jsx
|
2253
|
-
function LogoutButton({ supabaseClient, onLogout }) {
|
2254
|
-
const { signOut } = useAuth(supabaseClient);
|
2255
|
-
const handleLogout = async () => {
|
2256
|
-
await signOut();
|
2257
|
-
onLogout == null ? void 0 : onLogout();
|
2258
|
-
};
|
2259
|
-
return /* @__PURE__ */ React.createElement("button", { onClick: handleLogout }, "\u{1F6AA} Log out");
|
2260
|
-
}
|
2261
|
-
|
2262
2206
|
// src/utils.js
|
2263
2207
|
function isAdmin(user) {
|
2264
2208
|
return (user == null ? void 0 : user.role) === "admin";
|
2265
2209
|
}
|
2266
2210
|
|
2211
|
+
// src/supabaseClient.js
|
2212
|
+
import { createClient } from "@supabase/supabase-js";
|
2213
|
+
var supabase = null;
|
2214
|
+
function initializeSupabase(url, anonKey) {
|
2215
|
+
if (!url || !anonKey) {
|
2216
|
+
throw new Error("Supabase URL and Anon Key are required to initialize the client.");
|
2217
|
+
}
|
2218
|
+
supabase = createClient(url, anonKey);
|
2219
|
+
}
|
2220
|
+
|
2267
2221
|
// src/login.js
|
2268
2222
|
async function signInWithEmail(email, password) {
|
2269
2223
|
try {
|
@@ -2277,11 +2231,210 @@ async function signInWithEmail(email, password) {
|
|
2277
2231
|
return { session: null, error: err };
|
2278
2232
|
}
|
2279
2233
|
}
|
2234
|
+
|
2235
|
+
// src/register.js
|
2236
|
+
async function registerWithEmail(email, password, username, phone) {
|
2237
|
+
try {
|
2238
|
+
const { data: user, error } = await supabase.auth.signUp({
|
2239
|
+
email,
|
2240
|
+
password,
|
2241
|
+
options: {
|
2242
|
+
data: {
|
2243
|
+
username,
|
2244
|
+
// Store the display name
|
2245
|
+
phone
|
2246
|
+
// Store the phone number
|
2247
|
+
}
|
2248
|
+
}
|
2249
|
+
});
|
2250
|
+
return { user, error };
|
2251
|
+
} catch (err) {
|
2252
|
+
console.error("Unexpected error during registration:", err);
|
2253
|
+
return { user: null, error: err };
|
2254
|
+
}
|
2255
|
+
}
|
2256
|
+
|
2257
|
+
// src/logout.js
|
2258
|
+
async function logout() {
|
2259
|
+
try {
|
2260
|
+
const { error } = await supabase.auth.signOut();
|
2261
|
+
if (error) {
|
2262
|
+
console.error("Error during logout:", error);
|
2263
|
+
}
|
2264
|
+
return { error };
|
2265
|
+
} catch (err) {
|
2266
|
+
console.error("Unexpected error during logout:", err);
|
2267
|
+
return { error: err };
|
2268
|
+
}
|
2269
|
+
}
|
2270
|
+
|
2271
|
+
// src/components/LoginRegisterFlow.jsx
|
2272
|
+
var import_react2 = __toESM(require_react());
|
2273
|
+
function LoginRegisterFlow() {
|
2274
|
+
const [mode, setMode] = (0, import_react2.useState)("login");
|
2275
|
+
const [identifier, setIdentifier] = (0, import_react2.useState)("");
|
2276
|
+
const [password, setPassword] = (0, import_react2.useState)("");
|
2277
|
+
const [username, setUsername] = (0, import_react2.useState)("");
|
2278
|
+
const [phone, setPhone] = (0, import_react2.useState)("");
|
2279
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
2280
|
+
const handleLogin = async (e) => {
|
2281
|
+
e.preventDefault();
|
2282
|
+
const { error: error2 } = await signInWithEmail(identifier, password);
|
2283
|
+
setError(error2 ? error2.message : null);
|
2284
|
+
};
|
2285
|
+
const handleRegister = async (e) => {
|
2286
|
+
e.preventDefault();
|
2287
|
+
const { error: error2 } = await registerWithEmail(identifier, password, username, phone);
|
2288
|
+
setError(error2 ? error2.message : null);
|
2289
|
+
};
|
2290
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", null, /* @__PURE__ */ import_react2.default.createElement("button", { onClick: () => setMode("login") }, "Login"), /* @__PURE__ */ import_react2.default.createElement("button", { onClick: () => setMode("register") }, "Register"), mode === "login" ? /* @__PURE__ */ import_react2.default.createElement("form", { onSubmit: handleLogin }, /* @__PURE__ */ import_react2.default.createElement(
|
2291
|
+
"input",
|
2292
|
+
{
|
2293
|
+
type: "text",
|
2294
|
+
placeholder: "Email, phone, or username",
|
2295
|
+
value: identifier,
|
2296
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2297
|
+
}
|
2298
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2299
|
+
"input",
|
2300
|
+
{
|
2301
|
+
type: "password",
|
2302
|
+
placeholder: "Password",
|
2303
|
+
value: password,
|
2304
|
+
onChange: (e) => setPassword(e.target.value)
|
2305
|
+
}
|
2306
|
+
), /* @__PURE__ */ import_react2.default.createElement("button", { type: "submit" }, "Login")) : /* @__PURE__ */ import_react2.default.createElement("form", { onSubmit: handleRegister }, /* @__PURE__ */ import_react2.default.createElement(
|
2307
|
+
"input",
|
2308
|
+
{
|
2309
|
+
type: "text",
|
2310
|
+
placeholder: "Email",
|
2311
|
+
value: identifier,
|
2312
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2313
|
+
}
|
2314
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2315
|
+
"input",
|
2316
|
+
{
|
2317
|
+
type: "password",
|
2318
|
+
placeholder: "Password",
|
2319
|
+
value: password,
|
2320
|
+
onChange: (e) => setPassword(e.target.value)
|
2321
|
+
}
|
2322
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2323
|
+
"input",
|
2324
|
+
{
|
2325
|
+
type: "text",
|
2326
|
+
placeholder: "Username (optional)",
|
2327
|
+
value: username,
|
2328
|
+
onChange: (e) => setUsername(e.target.value)
|
2329
|
+
}
|
2330
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
2331
|
+
"input",
|
2332
|
+
{
|
2333
|
+
type: "text",
|
2334
|
+
placeholder: "Phone (optional)",
|
2335
|
+
value: phone,
|
2336
|
+
onChange: (e) => setPhone(e.target.value)
|
2337
|
+
}
|
2338
|
+
), /* @__PURE__ */ import_react2.default.createElement("button", { type: "submit" }, "Register")), error && /* @__PURE__ */ import_react2.default.createElement("div", { style: { color: "red" } }, error));
|
2339
|
+
}
|
2340
|
+
|
2341
|
+
// src/components/LoginOnly.jsx
|
2342
|
+
var import_react3 = __toESM(require_react());
|
2343
|
+
function LoginOnly() {
|
2344
|
+
const [identifier, setIdentifier] = (0, import_react3.useState)("");
|
2345
|
+
const [password, setPassword] = (0, import_react3.useState)("");
|
2346
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
2347
|
+
const handleLogin = async (e) => {
|
2348
|
+
e.preventDefault();
|
2349
|
+
const { error: error2 } = await signInWithEmail(identifier, password);
|
2350
|
+
setError(error2 ? error2.message : null);
|
2351
|
+
};
|
2352
|
+
return /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handleLogin }, /* @__PURE__ */ import_react3.default.createElement(
|
2353
|
+
"input",
|
2354
|
+
{
|
2355
|
+
type: "text",
|
2356
|
+
placeholder: "Email, phone, or username",
|
2357
|
+
value: identifier,
|
2358
|
+
onChange: (e) => setIdentifier(e.target.value)
|
2359
|
+
}
|
2360
|
+
), /* @__PURE__ */ import_react3.default.createElement(
|
2361
|
+
"input",
|
2362
|
+
{
|
2363
|
+
type: "password",
|
2364
|
+
placeholder: "Password",
|
2365
|
+
value: password,
|
2366
|
+
onChange: (e) => setPassword(e.target.value)
|
2367
|
+
}
|
2368
|
+
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit" }, "Login"), error && /* @__PURE__ */ import_react3.default.createElement("div", { style: { color: "red" } }, error));
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
// src/components/RegisterOnly.jsx
|
2372
|
+
var import_react4 = __toESM(require_react());
|
2373
|
+
function RegisterOnly() {
|
2374
|
+
const [email, setEmail] = (0, import_react4.useState)("");
|
2375
|
+
const [password, setPassword] = (0, import_react4.useState)("");
|
2376
|
+
const [username, setUsername] = (0, import_react4.useState)("");
|
2377
|
+
const [phone, setPhone] = (0, import_react4.useState)("");
|
2378
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
2379
|
+
const handleRegister = async (e) => {
|
2380
|
+
e.preventDefault();
|
2381
|
+
const { error: error2 } = await registerWithEmail(email, password, username, phone);
|
2382
|
+
setError(error2 ? error2.message : null);
|
2383
|
+
};
|
2384
|
+
return /* @__PURE__ */ import_react4.default.createElement("form", { onSubmit: handleRegister }, /* @__PURE__ */ import_react4.default.createElement(
|
2385
|
+
"input",
|
2386
|
+
{
|
2387
|
+
type: "text",
|
2388
|
+
placeholder: "Email",
|
2389
|
+
value: email,
|
2390
|
+
onChange: (e) => setEmail(e.target.value)
|
2391
|
+
}
|
2392
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2393
|
+
"input",
|
2394
|
+
{
|
2395
|
+
type: "password",
|
2396
|
+
placeholder: "Password",
|
2397
|
+
value: password,
|
2398
|
+
onChange: (e) => setPassword(e.target.value)
|
2399
|
+
}
|
2400
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2401
|
+
"input",
|
2402
|
+
{
|
2403
|
+
type: "text",
|
2404
|
+
placeholder: "Username (optional)",
|
2405
|
+
value: username,
|
2406
|
+
onChange: (e) => setUsername(e.target.value)
|
2407
|
+
}
|
2408
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
2409
|
+
"input",
|
2410
|
+
{
|
2411
|
+
type: "text",
|
2412
|
+
placeholder: "Phone (optional)",
|
2413
|
+
value: phone,
|
2414
|
+
onChange: (e) => setPhone(e.target.value)
|
2415
|
+
}
|
2416
|
+
), /* @__PURE__ */ import_react4.default.createElement("button", { type: "submit" }, "Register"), error && /* @__PURE__ */ import_react4.default.createElement("div", { style: { color: "red" } }, error));
|
2417
|
+
}
|
2418
|
+
|
2419
|
+
// src/components/LogoutButton.jsx
|
2420
|
+
var import_react5 = __toESM(require_react());
|
2421
|
+
function LogoutButton() {
|
2422
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
2423
|
+
const handleLogout = async () => {
|
2424
|
+
const { error: error2 } = await logout();
|
2425
|
+
setError(error2 ? error2.message : null);
|
2426
|
+
};
|
2427
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement("button", { onClick: handleLogout }, "Logout"), error && /* @__PURE__ */ import_react5.default.createElement("div", { style: { color: "red" } }, error));
|
2428
|
+
}
|
2280
2429
|
export {
|
2281
|
-
|
2430
|
+
LoginOnly,
|
2431
|
+
LoginRegisterFlow,
|
2282
2432
|
LogoutButton,
|
2433
|
+
RegisterOnly,
|
2283
2434
|
initializeSupabase,
|
2284
2435
|
isAdmin,
|
2436
|
+
logout,
|
2437
|
+
registerWithEmail,
|
2285
2438
|
signInWithEmail,
|
2286
2439
|
supabase,
|
2287
2440
|
useAuth
|
package/package.json
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { signInWithEmail } from '../login';
|
3
|
+
|
4
|
+
export default function LoginOnly() {
|
5
|
+
const [identifier, setIdentifier] = useState('');
|
6
|
+
const [password, setPassword] = useState('');
|
7
|
+
const [error, setError] = useState(null);
|
8
|
+
|
9
|
+
const handleLogin = async (e) => {
|
10
|
+
e.preventDefault();
|
11
|
+
const { error } = await signInWithEmail(identifier, password);
|
12
|
+
setError(error ? error.message : null);
|
13
|
+
};
|
14
|
+
|
15
|
+
return (
|
16
|
+
<form onSubmit={handleLogin}>
|
17
|
+
<input
|
18
|
+
type="text"
|
19
|
+
placeholder="Email, phone, or username"
|
20
|
+
value={identifier}
|
21
|
+
onChange={e => setIdentifier(e.target.value)}
|
22
|
+
/>
|
23
|
+
<input
|
24
|
+
type="password"
|
25
|
+
placeholder="Password"
|
26
|
+
value={password}
|
27
|
+
onChange={e => setPassword(e.target.value)}
|
28
|
+
/>
|
29
|
+
<button type="submit">Login</button>
|
30
|
+
{error && <div style={{ color: 'red' }}>{error}</div>}
|
31
|
+
</form>
|
32
|
+
);
|
33
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { signInWithEmail } from '../login';
|
3
|
+
import { registerWithEmail } from '../register';
|
4
|
+
|
5
|
+
export default function LoginRegisterFlow() {
|
6
|
+
const [mode, setMode] = useState('login');
|
7
|
+
const [identifier, setIdentifier] = useState('');
|
8
|
+
const [password, setPassword] = useState('');
|
9
|
+
const [username, setUsername] = useState('');
|
10
|
+
const [phone, setPhone] = useState('');
|
11
|
+
const [error, setError] = useState(null);
|
12
|
+
|
13
|
+
const handleLogin = async (e) => {
|
14
|
+
e.preventDefault();
|
15
|
+
const { error } = await signInWithEmail(identifier, password);
|
16
|
+
setError(error ? error.message : null);
|
17
|
+
};
|
18
|
+
|
19
|
+
const handleRegister = async (e) => {
|
20
|
+
e.preventDefault();
|
21
|
+
const { error } = await registerWithEmail(identifier, password, username, phone);
|
22
|
+
setError(error ? error.message : null);
|
23
|
+
};
|
24
|
+
|
25
|
+
return (
|
26
|
+
<div>
|
27
|
+
<button onClick={() => setMode('login')}>Login</button>
|
28
|
+
<button onClick={() => setMode('register')}>Register</button>
|
29
|
+
{mode === 'login' ? (
|
30
|
+
<form onSubmit={handleLogin}>
|
31
|
+
<input
|
32
|
+
type="text"
|
33
|
+
placeholder="Email, phone, or username"
|
34
|
+
value={identifier}
|
35
|
+
onChange={e => setIdentifier(e.target.value)}
|
36
|
+
/>
|
37
|
+
<input
|
38
|
+
type="password"
|
39
|
+
placeholder="Password"
|
40
|
+
value={password}
|
41
|
+
onChange={e => setPassword(e.target.value)}
|
42
|
+
/>
|
43
|
+
<button type="submit">Login</button>
|
44
|
+
</form>
|
45
|
+
) : (
|
46
|
+
<form onSubmit={handleRegister}>
|
47
|
+
<input
|
48
|
+
type="text"
|
49
|
+
placeholder="Email"
|
50
|
+
value={identifier}
|
51
|
+
onChange={e => setIdentifier(e.target.value)}
|
52
|
+
/>
|
53
|
+
<input
|
54
|
+
type="password"
|
55
|
+
placeholder="Password"
|
56
|
+
value={password}
|
57
|
+
onChange={e => setPassword(e.target.value)}
|
58
|
+
/>
|
59
|
+
<input
|
60
|
+
type="text"
|
61
|
+
placeholder="Username (optional)"
|
62
|
+
value={username}
|
63
|
+
onChange={e => setUsername(e.target.value)}
|
64
|
+
/>
|
65
|
+
<input
|
66
|
+
type="text"
|
67
|
+
placeholder="Phone (optional)"
|
68
|
+
value={phone}
|
69
|
+
onChange={e => setPhone(e.target.value)}
|
70
|
+
/>
|
71
|
+
<button type="submit">Register</button>
|
72
|
+
</form>
|
73
|
+
)}
|
74
|
+
{error && <div style={{ color: 'red' }}>{error}</div>}
|
75
|
+
</div>
|
76
|
+
);
|
77
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { logout } from '../logout';
|
3
|
+
|
4
|
+
export default function LogoutButton() {
|
5
|
+
const [error, setError] = useState(null);
|
6
|
+
|
7
|
+
const handleLogout = async () => {
|
8
|
+
const { error } = await logout();
|
9
|
+
setError(error ? error.message : null);
|
10
|
+
};
|
11
|
+
|
12
|
+
return (
|
13
|
+
<div>
|
14
|
+
<button onClick={handleLogout}>Logout</button>
|
15
|
+
{error && <div style={{ color: 'red' }}>{error}</div>}
|
16
|
+
</div>
|
17
|
+
);
|
18
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { registerWithEmail } from '../register';
|
3
|
+
|
4
|
+
export default function RegisterOnly() {
|
5
|
+
const [email, setEmail] = useState('');
|
6
|
+
const [password, setPassword] = useState('');
|
7
|
+
const [username, setUsername] = useState('');
|
8
|
+
const [phone, setPhone] = useState('');
|
9
|
+
const [error, setError] = useState(null);
|
10
|
+
|
11
|
+
const handleRegister = async (e) => {
|
12
|
+
e.preventDefault();
|
13
|
+
const { error } = await registerWithEmail(email, password, username, phone);
|
14
|
+
setError(error ? error.message : null);
|
15
|
+
};
|
16
|
+
|
17
|
+
return (
|
18
|
+
<form onSubmit={handleRegister}>
|
19
|
+
<input
|
20
|
+
type="text"
|
21
|
+
placeholder="Email"
|
22
|
+
value={email}
|
23
|
+
onChange={e => setEmail(e.target.value)}
|
24
|
+
/>
|
25
|
+
<input
|
26
|
+
type="password"
|
27
|
+
placeholder="Password"
|
28
|
+
value={password}
|
29
|
+
onChange={e => setPassword(e.target.value)}
|
30
|
+
/>
|
31
|
+
<input
|
32
|
+
type="text"
|
33
|
+
placeholder="Username (optional)"
|
34
|
+
value={username}
|
35
|
+
onChange={e => setUsername(e.target.value)}
|
36
|
+
/>
|
37
|
+
<input
|
38
|
+
type="text"
|
39
|
+
placeholder="Phone (optional)"
|
40
|
+
value={phone}
|
41
|
+
onChange={e => setPhone(e.target.value)}
|
42
|
+
/>
|
43
|
+
<button type="submit">Register</button>
|
44
|
+
{error && <div style={{ color: 'red' }}>{error}</div>}
|
45
|
+
</form>
|
46
|
+
);
|
47
|
+
}
|
package/src/index.js
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
export { default as AuthWrapper } from './AuthWrapper';
|
2
|
-
export { default as LogoutButton } from './LogoutButton';
|
3
1
|
export { useAuth } from './useAuth';
|
4
2
|
export { isAdmin } from './utils';
|
5
3
|
export { supabase } from './supabaseClient';
|
6
4
|
export { signInWithEmail } from './login'; // Add this line
|
7
|
-
export { initializeSupabase } from './supabaseClient';
|
5
|
+
export { initializeSupabase } from './supabaseClient';
|
6
|
+
export { registerWithEmail } from './register';
|
7
|
+
export { logout } from './logout';
|
8
|
+
|
9
|
+
export { default as LoginRegisterFlow } from './components/LoginRegisterFlow';
|
10
|
+
export { default as LoginOnly } from './components/LoginOnly';
|
11
|
+
export { default as RegisterOnly } from './components/RegisterOnly';
|
12
|
+
export { default as LogoutButton } from './components/LogoutButton';
|
package/src/logout.js
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
import { supabase } from './supabaseClient';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Logs out the currently authenticated user.
|
5
|
+
* @returns {Promise<{ error: any }>} - The error (if any) during logout.
|
6
|
+
*/
|
7
|
+
export async function logout() {
|
8
|
+
try {
|
9
|
+
const { error } = await supabase.auth.signOut();
|
10
|
+
if (error) {
|
11
|
+
console.error('Error during logout:', error);
|
12
|
+
}
|
13
|
+
return { error };
|
14
|
+
} catch (err) {
|
15
|
+
console.error('Unexpected error during logout:', err);
|
16
|
+
return { error: err };
|
17
|
+
}
|
18
|
+
}
|
package/src/register.js
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
import { supabase } from './supabaseClient';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Registers a new user using email, password, and optional username and phone number.
|
5
|
+
* @param {string} email - The user's email address.
|
6
|
+
* @param {string} password - The user's password.
|
7
|
+
* @param {string} [username] - The user's display name (optional).
|
8
|
+
* @param {string} [phone] - The user's phone number (optional).
|
9
|
+
* @returns {Promise<{ user: any, error: any }>} - The user and error (if any).
|
10
|
+
*/
|
11
|
+
export async function registerWithEmail(email, password, username, phone) {
|
12
|
+
try {
|
13
|
+
const { data: user, error } = await supabase.auth.signUp({
|
14
|
+
email,
|
15
|
+
password,
|
16
|
+
options: {
|
17
|
+
data: {
|
18
|
+
username, // Store the display name
|
19
|
+
phone, // Store the phone number
|
20
|
+
},
|
21
|
+
},
|
22
|
+
});
|
23
|
+
|
24
|
+
return { user, error };
|
25
|
+
} catch (err) {
|
26
|
+
console.error('Unexpected error during registration:', err);
|
27
|
+
return { user: null, error: err };
|
28
|
+
}
|
29
|
+
}
|
package/src/AuthWrapper.jsx
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
import { useState, useEffect } from 'react'
|
2
|
-
import { Auth } from '@supabase/auth-ui-react'
|
3
|
-
import { ThemeSupa } from '@supabase/auth-ui-shared'
|
4
|
-
import { supabase } from './supabaseClient'
|
5
|
-
|
6
|
-
export default function AuthWrapper({ onAuth, providers = ['google', 'github'], theme = 'dark' }) {
|
7
|
-
if (!supabase) {
|
8
|
-
throw new Error('Supabase client is not initialized. Call initializeSupabase() before using AuthWrapper.')
|
9
|
-
}
|
10
|
-
|
11
|
-
const [session, setSession] = useState(null)
|
12
|
-
|
13
|
-
useEffect(() => {
|
14
|
-
supabase.auth.getSession().then(({ data: { session } }) => {
|
15
|
-
setSession(session)
|
16
|
-
if (session) onAuth?.(session)
|
17
|
-
})
|
18
|
-
|
19
|
-
const { data: subscription } = supabase.auth.onAuthStateChange((_event, session) => {
|
20
|
-
setSession(session)
|
21
|
-
if (session) onAuth?.(session)
|
22
|
-
})
|
23
|
-
|
24
|
-
return () => subscription?.unsubscribe()
|
25
|
-
}, [onAuth])
|
26
|
-
|
27
|
-
if (!session) {
|
28
|
-
return (
|
29
|
-
<Auth
|
30
|
-
supabaseClient={supabase}
|
31
|
-
appearance={{ theme: ThemeSupa }}
|
32
|
-
providers={providers}
|
33
|
-
theme={theme}
|
34
|
-
/>
|
35
|
-
)
|
36
|
-
}
|
37
|
-
|
38
|
-
return <div>✅ Logged in as: {session.user.email}</div>
|
39
|
-
}
|
package/src/LogoutButton.jsx
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
import { useAuth } from './useAuth'
|
2
|
-
|
3
|
-
export default function LogoutButton({ supabaseClient, onLogout }) {
|
4
|
-
const { signOut } = useAuth(supabaseClient)
|
5
|
-
|
6
|
-
const handleLogout = async () => {
|
7
|
-
await signOut()
|
8
|
-
onLogout?.()
|
9
|
-
}
|
10
|
-
|
11
|
-
return <button onClick={handleLogout}>🚪 Log out</button>
|
12
|
-
}
|