Spaces:
Running
Running
umer6016
commited on
Commit
·
5ffd058
1
Parent(s):
40fa926
Fix login persistence bug and URL input UX
Browse files- frontend/src/App.jsx +94 -37
frontend/src/App.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { useRef, useState } from "react";
|
| 2 |
import { supabase } from "./supabaseClient";
|
| 3 |
|
| 4 |
const getEnv = (key) => {
|
|
@@ -34,7 +34,7 @@ export default function App() {
|
|
| 34 |
const [session, setSession] = useState(null);
|
| 35 |
const [status, setStatus] = useState("");
|
| 36 |
const [forceRefresh, setForceRefresh] = useState(false);
|
| 37 |
-
const [urlValue, setUrlValue] = useState("
|
| 38 |
const [jobResult, setJobResult] = useState(null);
|
| 39 |
const [systemPrompt, setSystemPrompt] = useState("");
|
| 40 |
const [siteName, setSiteName] = useState("Bot");
|
|
@@ -56,6 +56,44 @@ export default function App() {
|
|
| 56 |
const [signupPassword, setSignupPassword] = useState("");
|
| 57 |
const [summaryVisible, setSummaryVisible] = useState(false);
|
| 58 |
const [summaryData, setSummaryData] = useState({ pages: 0, searches: 0 });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
// Refs to avoid re-rendering while typing (prevents cursor jump/blur)
|
| 61 |
const loginEmailRef = useRef(null);
|
|
@@ -68,7 +106,6 @@ export default function App() {
|
|
| 68 |
const otpPassRef = useRef(null);
|
| 69 |
const otpCodeRef = useRef(null);
|
| 70 |
const urlInputRef = useRef(null);
|
| 71 |
-
const defaultUrl = "https://example.com";
|
| 72 |
|
| 73 |
const handleSignup = async () => {
|
| 74 |
const email = signupEmailRef.current?.value?.trim() || "";
|
|
@@ -241,7 +278,11 @@ export default function App() {
|
|
| 241 |
};
|
| 242 |
|
| 243 |
const runJob = async () => {
|
| 244 |
-
const targetUrl = (urlInputRef.current?.value || "").trim()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
setIsRunning(true);
|
| 246 |
setStatus("Submitting job...");
|
| 247 |
setJobResult(null);
|
|
@@ -513,52 +554,68 @@ export default function App() {
|
|
| 513 |
<div className="app-shell">
|
| 514 |
<Header />
|
| 515 |
|
| 516 |
-
{
|
| 517 |
<div className="auth-page">
|
| 518 |
<div className="auth-stage">
|
| 519 |
<div className="auth-card-wrap">
|
| 520 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
| 521 |
</div>
|
| 522 |
</div>
|
| 523 |
</div>
|
| 524 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
|
|
|
|
|
|
| 531 |
</div>
|
| 532 |
-
|
| 533 |
-
</div>
|
| 534 |
-
)}
|
| 535 |
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
|
|
|
|
|
|
| 541 |
</div>
|
| 542 |
-
|
| 543 |
-
</div>
|
| 544 |
-
)}
|
| 545 |
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
|
|
|
|
|
|
| 551 |
</div>
|
| 552 |
-
|
| 553 |
-
</div>
|
| 554 |
-
)}
|
| 555 |
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
|
|
|
|
|
|
| 562 |
)}
|
| 563 |
</div>
|
| 564 |
);
|
|
|
|
| 1 |
+
import { useRef, useState, useEffect } from "react";
|
| 2 |
import { supabase } from "./supabaseClient";
|
| 3 |
|
| 4 |
const getEnv = (key) => {
|
|
|
|
| 34 |
const [session, setSession] = useState(null);
|
| 35 |
const [status, setStatus] = useState("");
|
| 36 |
const [forceRefresh, setForceRefresh] = useState(false);
|
| 37 |
+
const [urlValue, setUrlValue] = useState("");
|
| 38 |
const [jobResult, setJobResult] = useState(null);
|
| 39 |
const [systemPrompt, setSystemPrompt] = useState("");
|
| 40 |
const [siteName, setSiteName] = useState("Bot");
|
|
|
|
| 56 |
const [signupPassword, setSignupPassword] = useState("");
|
| 57 |
const [summaryVisible, setSummaryVisible] = useState(false);
|
| 58 |
const [summaryData, setSummaryData] = useState({ pages: 0, searches: 0 });
|
| 59 |
+
const [isSessionChecking, setIsSessionChecking] = useState(true); // [NEW] Loading state for initial session check
|
| 60 |
+
|
| 61 |
+
// [NEW] Check for existing session on mount
|
| 62 |
+
useEffect(() => {
|
| 63 |
+
// 1. Get initial session
|
| 64 |
+
supabase.auth.getSession().then(({ data: { session } }) => {
|
| 65 |
+
if (session) {
|
| 66 |
+
setSession(session);
|
| 67 |
+
setEmailDisplay(session.user?.email || "");
|
| 68 |
+
const fn = session.user?.user_metadata?.first_name;
|
| 69 |
+
setFirstNameDisplay(fn || (session.user?.email ? session.user.email.split("@")[0] : ""));
|
| 70 |
+
setView("app");
|
| 71 |
+
setStatus("Restored session.");
|
| 72 |
+
}
|
| 73 |
+
setIsSessionChecking(false);
|
| 74 |
+
});
|
| 75 |
+
|
| 76 |
+
// 2. Listen for changes (login, logout, auto-refresh)
|
| 77 |
+
const {
|
| 78 |
+
data: { subscription },
|
| 79 |
+
} = supabase.auth.onAuthStateChange((_event, session) => {
|
| 80 |
+
setSession(session);
|
| 81 |
+
if (session) {
|
| 82 |
+
setEmailDisplay(session.user?.email || "");
|
| 83 |
+
const fn = session.user?.user_metadata?.first_name;
|
| 84 |
+
setFirstNameDisplay(fn || (session.user?.email ? session.user.email.split("@")[0] : ""));
|
| 85 |
+
// Only switch to app if we were in a login/signup flow to avoid disrupting user
|
| 86 |
+
setView((prev) => (prev === "login" || prev === "signup" || prev === "otp" || prev === "reset" ? "app" : prev));
|
| 87 |
+
} else {
|
| 88 |
+
// If logged out
|
| 89 |
+
setView("login");
|
| 90 |
+
setEmailDisplay("");
|
| 91 |
+
setFirstNameDisplay("");
|
| 92 |
+
}
|
| 93 |
+
});
|
| 94 |
+
|
| 95 |
+
return () => subscription.unsubscribe();
|
| 96 |
+
}, []);
|
| 97 |
|
| 98 |
// Refs to avoid re-rendering while typing (prevents cursor jump/blur)
|
| 99 |
const loginEmailRef = useRef(null);
|
|
|
|
| 106 |
const otpPassRef = useRef(null);
|
| 107 |
const otpCodeRef = useRef(null);
|
| 108 |
const urlInputRef = useRef(null);
|
|
|
|
| 109 |
|
| 110 |
const handleSignup = async () => {
|
| 111 |
const email = signupEmailRef.current?.value?.trim() || "";
|
|
|
|
| 278 |
};
|
| 279 |
|
| 280 |
const runJob = async () => {
|
| 281 |
+
const targetUrl = (urlInputRef.current?.value || "").trim();
|
| 282 |
+
if (!targetUrl) {
|
| 283 |
+
setStatus("Please enter a URL.");
|
| 284 |
+
return;
|
| 285 |
+
}
|
| 286 |
setIsRunning(true);
|
| 287 |
setStatus("Submitting job...");
|
| 288 |
setJobResult(null);
|
|
|
|
| 554 |
<div className="app-shell">
|
| 555 |
<Header />
|
| 556 |
|
| 557 |
+
{isSessionChecking ? (
|
| 558 |
<div className="auth-page">
|
| 559 |
<div className="auth-stage">
|
| 560 |
<div className="auth-card-wrap">
|
| 561 |
+
<Panel title="Loading..." subtitle="Checking authentication status...">
|
| 562 |
+
<div style={{ textAlign: "center", padding: "20px" }}>
|
| 563 |
+
<div className="loading" style={{ margin: "0 auto" }}></div>
|
| 564 |
+
</div>
|
| 565 |
+
</Panel>
|
| 566 |
</div>
|
| 567 |
</div>
|
| 568 |
</div>
|
| 569 |
+
) : (
|
| 570 |
+
<>
|
| 571 |
+
{view === "login" && (
|
| 572 |
+
<div className="auth-page">
|
| 573 |
+
<div className="auth-stage">
|
| 574 |
+
<div className="auth-card-wrap">
|
| 575 |
+
<LoginCard />
|
| 576 |
+
</div>
|
| 577 |
+
</div>
|
| 578 |
+
</div>
|
| 579 |
+
)}
|
| 580 |
|
| 581 |
+
{view === "signup" && (
|
| 582 |
+
<div className="auth-page">
|
| 583 |
+
<div className="auth-stage">
|
| 584 |
+
<div className="auth-card-wrap">
|
| 585 |
+
<SignupCard />
|
| 586 |
+
</div>
|
| 587 |
+
</div>
|
| 588 |
</div>
|
| 589 |
+
)}
|
|
|
|
|
|
|
| 590 |
|
| 591 |
+
{view === "reset" && (
|
| 592 |
+
<div className="auth-page">
|
| 593 |
+
<div className="auth-stage">
|
| 594 |
+
<div className="auth-card-wrap">
|
| 595 |
+
<ResetCard />
|
| 596 |
+
</div>
|
| 597 |
+
</div>
|
| 598 |
</div>
|
| 599 |
+
)}
|
|
|
|
|
|
|
| 600 |
|
| 601 |
+
{view === "otp" && (
|
| 602 |
+
<div className="auth-page">
|
| 603 |
+
<div className="auth-stage">
|
| 604 |
+
<div className="auth-card-wrap">
|
| 605 |
+
<OtpCard />
|
| 606 |
+
</div>
|
| 607 |
+
</div>
|
| 608 |
</div>
|
| 609 |
+
)}
|
|
|
|
|
|
|
| 610 |
|
| 611 |
+
{view === "app" && (
|
| 612 |
+
<div className="main-page">
|
| 613 |
+
<div className="main-card-wrap">
|
| 614 |
+
<AppCards />
|
| 615 |
+
</div>
|
| 616 |
+
</div>
|
| 617 |
+
)}
|
| 618 |
+
</>
|
| 619 |
)}
|
| 620 |
</div>
|
| 621 |
);
|