more
This commit is contained in:
@@ -12,141 +12,9 @@ import TierPicker from "../../components/TierPicker";
|
|||||||
import "./Subscribe.css";
|
import "./Subscribe.css";
|
||||||
|
|
||||||
const STEPS = ["Create Account", "Choose Plan"];
|
const STEPS = ["Create Account", "Choose Plan"];
|
||||||
|
|
||||||
export default function Subscribe() {
|
export default function Subscribe() {
|
||||||
const { currentUser, signup } = useAuth();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
|
||||||
|
|
||||||
const hasPaymentReturn = searchParams.get("payment") === "success";
|
|
||||||
const [step, setStep] = useState(hasPaymentReturn || currentUser ? 2 : 1);
|
|
||||||
const [loading, setLoading] = useState(hasPaymentReturn);
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
|
|
||||||
const [data, setData] = useState({
|
|
||||||
selectedTier: "",
|
|
||||||
email: "",
|
|
||||||
password: "",
|
|
||||||
confirmPassword: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
function set(field, value) {
|
|
||||||
setData((prev) => ({ ...prev, [field]: value }));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Stripe payment returns
|
|
||||||
useEffect(() => {
|
|
||||||
const payment = searchParams.get("payment");
|
|
||||||
const sessionId = searchParams.get("session_id");
|
|
||||||
|
|
||||||
if (payment === "cancelled") {
|
|
||||||
setSearchParams({}, { replace: true });
|
|
||||||
setStep(2);
|
|
||||||
setError("Payment was cancelled. Please try again.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payment !== "success" || !sessionId) return;
|
|
||||||
|
|
||||||
// Phase 1: no account yet — create it. Auth state change remounts the
|
|
||||||
// component (App.jsx swaps route trees) and Phase 2 runs on the next mount.
|
|
||||||
if (!currentUser) {
|
|
||||||
const savedEmail = sessionStorage.getItem("kp_onboard_email");
|
|
||||||
const savedPw = sessionStorage.getItem("kp_onboard_pw");
|
|
||||||
if (!savedEmail || !savedPw) {
|
|
||||||
setSearchParams({}, { replace: true });
|
|
||||||
setError("Session expired. Please start the signup process again.");
|
|
||||||
setStep(1);
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
signup(savedEmail, savedPw).catch((err) => {
|
|
||||||
setSearchParams({}, { replace: true });
|
|
||||||
setError("Account creation failed: " + err.message);
|
|
||||||
setStep(1);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase 2: authenticated — verify the checkout and go to the dashboard.
|
|
||||||
setSearchParams({}, { replace: true });
|
|
||||||
setLoading(true);
|
|
||||||
sessionStorage.removeItem("kp_onboard_email");
|
|
||||||
sessionStorage.removeItem("kp_onboard_pw");
|
|
||||||
|
|
||||||
verifyCheckoutSession(sessionId)
|
|
||||||
.then(() => {
|
|
||||||
navigate("/addresses", { replace: true });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setError("Payment verification failed: " + err.message);
|
|
||||||
setStep(2);
|
|
||||||
})
|
|
||||||
.finally(() => setLoading(false));
|
|
||||||
}, [currentUser, searchParams, setSearchParams, signup, navigate]);
|
|
||||||
|
|
||||||
// ── Step handlers ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function handleStep1() {
|
|
||||||
setError("");
|
|
||||||
if (!data.email || !data.password || !data.confirmPassword) {
|
|
||||||
setError("Please fill in all fields");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.password !== data.confirmPassword) {
|
|
||||||
setError("Passwords do not match");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.password.length < 6) {
|
|
||||||
setError("Password must be at least 6 characters");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStep(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleStep2() {
|
|
||||||
setError("");
|
|
||||||
if (!data.selectedTier) {
|
|
||||||
setError("Please select a plan to continue");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
if (data.selectedTier === "free") {
|
|
||||||
if (!currentUser) {
|
|
||||||
await signup(data.email, data.password);
|
|
||||||
}
|
|
||||||
await activateFreeTier();
|
|
||||||
navigate("/addresses", { replace: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionStorage.setItem("kp_onboard_email", data.email);
|
|
||||||
sessionStorage.setItem("kp_onboard_pw", data.password);
|
|
||||||
const { url } = await createOnboardingCheckout(
|
|
||||||
data.email,
|
|
||||||
data.selectedTier,
|
|
||||||
);
|
|
||||||
window.location.href = url;
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code === "auth/email-already-in-use") {
|
|
||||||
setError("Email already in use. Try logging in instead.");
|
|
||||||
} else if (err.code === "auth/invalid-email") {
|
|
||||||
setError("Invalid email address");
|
|
||||||
} else if (err.code === "auth/weak-password") {
|
|
||||||
setError("Password is too weak");
|
|
||||||
} else {
|
|
||||||
setError("Failed to process plan selection: " + err.message);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Progress bar ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function ProgressBar() {
|
function ProgressBar() {
|
||||||
return (
|
return (
|
||||||
@@ -165,8 +33,7 @@ export default function Subscribe() {
|
|||||||
<div key={label} className="progress-bar__step">
|
<div key={label} className="progress-bar__step">
|
||||||
{i > 0 && (
|
{i > 0 && (
|
||||||
<div
|
<div
|
||||||
className={`progress-bar__connector ${
|
className={`progress-bar__connector ${done || active
|
||||||
done || active
|
|
||||||
? "progress-bar__connector--active"
|
? "progress-bar__connector--active"
|
||||||
: "progress-bar__connector--inactive"
|
: "progress-bar__connector--inactive"
|
||||||
}`}
|
}`}
|
||||||
@@ -177,8 +44,7 @@ export default function Subscribe() {
|
|||||||
{done ? "\u2713" : stepNum}
|
{done ? "\u2713" : stepNum}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`progress-bar__label ${
|
className={`progress-bar__label ${active
|
||||||
active
|
|
||||||
? "progress-bar__label--active"
|
? "progress-bar__label--active"
|
||||||
: "progress-bar__label--inactive"
|
: "progress-bar__label--inactive"
|
||||||
}`}
|
}`}
|
||||||
|
|||||||
Reference in New Issue
Block a user