Initial commit: dashboard
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
/**
|
||||
* Install session from the URL hash BEFORE React AuthProvider runs.
|
||||
* Cross-subdomain localStorage is empty until this runs; without it,
|
||||
* ProtectedRoute saw ?businessId= and bounced admins back to /businesses.
|
||||
*/
|
||||
const HANDOFF_BOOT = `
|
||||
(function () {
|
||||
try {
|
||||
var raw = location.hash ? location.hash.replace(/^#/, "") : "";
|
||||
if (!raw) return;
|
||||
var p = new URLSearchParams(raw);
|
||||
var access = p.get("access");
|
||||
var refresh = p.get("refresh");
|
||||
var businessId = p.get("businessId");
|
||||
var clearManaged = p.get("clearManaged") === "1";
|
||||
var next = p.get("next") || "/profile";
|
||||
if (!access || !refresh) return;
|
||||
|
||||
localStorage.setItem("marketplace_access_token", access);
|
||||
localStorage.setItem("marketplace_refresh_token", refresh);
|
||||
|
||||
var root = "localhost";
|
||||
try {
|
||||
// Best-effort shared cookie for *.localhost / prod root
|
||||
document.cookie =
|
||||
"marketplace_access_token=" +
|
||||
encodeURIComponent(access) +
|
||||
"; Path=/; Max-Age=1209600; SameSite=Lax; Domain=" +
|
||||
root;
|
||||
document.cookie =
|
||||
"marketplace_refresh_token=" +
|
||||
encodeURIComponent(refresh) +
|
||||
"; Path=/; Max-Age=1209600; SameSite=Lax; Domain=" +
|
||||
root;
|
||||
} catch (e) {}
|
||||
|
||||
if (businessId) {
|
||||
localStorage.setItem("marketplace_managed_business_id", businessId);
|
||||
sessionStorage.setItem("marketplace_managed_business_id", businessId);
|
||||
} else if (clearManaged) {
|
||||
localStorage.removeItem("marketplace_managed_business_id");
|
||||
sessionStorage.removeItem("marketplace_managed_business_id");
|
||||
}
|
||||
|
||||
var target = next.charAt(0) === "/" ? next : "/" + next;
|
||||
location.replace(target);
|
||||
} catch (e) {}
|
||||
})();
|
||||
`;
|
||||
|
||||
export default function AuthHandoffLayout({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<script dangerouslySetInnerHTML={{ __html: HANDOFF_BOOT }} />
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* Fallback UI if the inline boot script did not redirect
|
||||
* (e.g. missing hash). Prefer the layout script for session install.
|
||||
*/
|
||||
export default function AuthHandoffPage() {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
display: "grid",
|
||||
placeItems: "center",
|
||||
background: "#f6f6f6",
|
||||
fontSize: 12,
|
||||
letterSpacing: "0.2em",
|
||||
textTransform: "uppercase",
|
||||
color: "#8e8e8e",
|
||||
padding: 24,
|
||||
textAlign: "center",
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
Opening business dashboard…
|
||||
<br />
|
||||
<span style={{ letterSpacing: "0.06em", textTransform: "none", marginTop: 12 }}>
|
||||
If this page stays here, go back and click Manage business again.
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user