but
This commit is contained in:
@@ -10,7 +10,7 @@ import AlertHistory from "./pages/alertHistory/AlertHistory";
|
||||
import Account from "./pages/user_account/Account";
|
||||
|
||||
export default function App() {
|
||||
const { currentUser } = useAuth();
|
||||
const { currentUser, isSubscribed } = useAuth();
|
||||
|
||||
if (!currentUser) {
|
||||
return (
|
||||
@@ -23,6 +23,16 @@ export default function App() {
|
||||
);
|
||||
}
|
||||
|
||||
if (!isSubscribed) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/subscribe" element={<Subscribe />} />
|
||||
<Route path="/account" element={<><Navbar /><Account /></>} />
|
||||
<Route path="*" element={<Navigate to="/subscribe" />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Navbar />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import "./UpgradeBanner.css";
|
||||
|
||||
export default function UpgradeBanner({ message, linkTo = "/account" }) {
|
||||
export default function UpgradeBanner({ message, linkTo = "/subscribe?upgrade=true" }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
|
||||
@@ -45,6 +45,7 @@ export function AuthProvider({ children }) {
|
||||
const [userTier, setUserTier] = useState("free");
|
||||
const [tierLimits, setTierLimits] = useState(DEFAULT_TIER_LIMITS);
|
||||
const [addressCount, setAddressCount] = useState(0);
|
||||
const [subscriptionStatus, setSubscriptionStatus] = useState("none");
|
||||
|
||||
const refreshAccount = useCallback(async () => {
|
||||
try {
|
||||
@@ -52,6 +53,7 @@ export function AuthProvider({ children }) {
|
||||
setUserTier(data.subscription_tier || "free");
|
||||
setTierLimits(data.tier_limits || DEFAULT_TIER_LIMITS);
|
||||
setAddressCount(data.address_count || 0);
|
||||
setSubscriptionStatus(data.subscription_status || "none");
|
||||
} catch {
|
||||
// account fetch can fail during onboarding before subscription is active
|
||||
}
|
||||
@@ -93,6 +95,7 @@ export function AuthProvider({ children }) {
|
||||
setUserTier("free");
|
||||
setTierLimits(DEFAULT_TIER_LIMITS);
|
||||
setAddressCount(0);
|
||||
setSubscriptionStatus("none");
|
||||
await signOut(auth);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
@@ -111,6 +114,9 @@ export function AuthProvider({ children }) {
|
||||
return unsubscribe;
|
||||
}, [refreshAccount]);
|
||||
|
||||
const isSubscribed =
|
||||
subscriptionStatus === "active" || subscriptionStatus === "trialing";
|
||||
|
||||
const value = {
|
||||
currentUser,
|
||||
signup,
|
||||
@@ -121,6 +127,8 @@ export function AuthProvider({ children }) {
|
||||
userTier,
|
||||
tierLimits,
|
||||
addressCount,
|
||||
subscriptionStatus,
|
||||
isSubscribed,
|
||||
refreshAccount,
|
||||
};
|
||||
|
||||
|
||||
@@ -397,6 +397,14 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
/* Tier-locked: greyed out, non-interactive overlay for features above the user's plan */
|
||||
.tier-locked {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
filter: grayscale(40%);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 480px) {
|
||||
html {
|
||||
|
||||
@@ -95,11 +95,9 @@ export default function Addresses() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{!atLimit && (
|
||||
<div className="mb-xl">
|
||||
<AddressForm onSubmit={handleAddressSubmit} />
|
||||
</div>
|
||||
)}
|
||||
<div className={`mb-xl${atLimit ? " tier-locked" : ""}`}>
|
||||
<AddressForm onSubmit={handleAddressSubmit} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Existing Tracked Addresses</h2>
|
||||
|
||||
@@ -382,12 +382,10 @@ export default function Alerts() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{!atAlertLimit && (
|
||||
<div className="mb-xl">
|
||||
<h3>Create New Alert</h3>
|
||||
<AlertForm onSubmit={handleAlertSubmit} />
|
||||
</div>
|
||||
)}
|
||||
<div className={`mb-xl${atAlertLimit ? " tier-locked" : ""}`}>
|
||||
<h3>Create New Alert</h3>
|
||||
<AlertForm onSubmit={handleAlertSubmit} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Active Alert Rules</h3>
|
||||
|
||||
@@ -34,6 +34,7 @@ export default function Subscribe() {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const hasPaymentReturn = searchParams.get("payment") === "success";
|
||||
const isUpgrade = searchParams.get("upgrade") === "true";
|
||||
const [step, setStep] = useState(hasPaymentReturn || currentUser ? 2 : 1);
|
||||
const [loading, setLoading] = useState(hasPaymentReturn);
|
||||
const [error, setError] = useState("");
|
||||
@@ -69,7 +70,7 @@ export default function Subscribe() {
|
||||
const tierLimits = TIER_LIMITS[data.selectedTier] || TIER_LIMITS.free;
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentUser) return;
|
||||
if (!currentUser || isUpgrade) return;
|
||||
getAddresses()
|
||||
.then((addresses) => {
|
||||
if (addresses.length > 0) {
|
||||
@@ -77,7 +78,7 @@ export default function Subscribe() {
|
||||
}
|
||||
})
|
||||
.catch(() => { });
|
||||
}, [currentUser, navigate]);
|
||||
}, [currentUser, navigate, isUpgrade]);
|
||||
|
||||
useEffect(() => {
|
||||
const payment = searchParams.get("payment");
|
||||
|
||||
Reference in New Issue
Block a user