mirror of
https://github.com/fosrl/pangolin.git
synced 2026-04-14 13:56:36 +00:00
Compare commits
4 Commits
1.17.1-s.0
...
1.17.1-s.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b18ea66def | ||
|
|
93998f9fd5 | ||
|
|
c554e69514 | ||
|
|
a6e10e55cc |
@@ -21,7 +21,8 @@ async function queryUser(userId: string) {
|
|||||||
serverAdmin: users.serverAdmin,
|
serverAdmin: users.serverAdmin,
|
||||||
idpName: idp.name,
|
idpName: idp.name,
|
||||||
idpId: users.idpId,
|
idpId: users.idpId,
|
||||||
locale: users.locale
|
locale: users.locale,
|
||||||
|
dateCreated: users.dateCreated
|
||||||
})
|
})
|
||||||
.from(users)
|
.from(users)
|
||||||
.leftJoin(idp, eq(users.idpId, idp.idpId))
|
.leftJoin(idp, eq(users.idpId, idp.idpId))
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ export async function myDevice(
|
|||||||
serverAdmin: users.serverAdmin,
|
serverAdmin: users.serverAdmin,
|
||||||
idpName: idp.name,
|
idpName: idp.name,
|
||||||
idpId: users.idpId,
|
idpId: users.idpId,
|
||||||
locale: users.locale
|
locale: users.locale,
|
||||||
|
dateCreated: users.dateCreated
|
||||||
})
|
})
|
||||||
.from(users)
|
.from(users)
|
||||||
.leftJoin(idp, eq(users.idpId, idp.idpId))
|
.leftJoin(idp, eq(users.idpId, idp.idpId))
|
||||||
|
|||||||
@@ -491,6 +491,10 @@ export default function BillingPage() {
|
|||||||
|
|
||||||
const currentPlanId = getCurrentPlanId();
|
const currentPlanId = getCurrentPlanId();
|
||||||
|
|
||||||
|
const visiblePlanOptions = planOptions.filter(
|
||||||
|
(plan) => plan.id !== "home" || currentPlanId === "home"
|
||||||
|
);
|
||||||
|
|
||||||
// Check if subscription is in a problematic state that requires attention
|
// Check if subscription is in a problematic state that requires attention
|
||||||
const hasProblematicSubscription = (): boolean => {
|
const hasProblematicSubscription = (): boolean => {
|
||||||
if (!tierSubscription?.subscription) return false;
|
if (!tierSubscription?.subscription) return false;
|
||||||
@@ -803,8 +807,8 @@ export default function BillingPage() {
|
|||||||
</SettingsSectionHeader>
|
</SettingsSectionHeader>
|
||||||
<SettingsSectionBody>
|
<SettingsSectionBody>
|
||||||
{/* Plan Cards Grid */}
|
{/* Plan Cards Grid */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-5 gap-4">
|
<div className={cn("grid grid-cols-1 gap-4", visiblePlanOptions.length === 5 ? "md:grid-cols-5" : "md:grid-cols-4")}>
|
||||||
{planOptions.filter((plan) => plan.id !== "home" || currentPlanId === "home").map((plan) => {
|
{visiblePlanOptions.map((plan) => {
|
||||||
const isCurrentPlan = plan.id === currentPlanId;
|
const isCurrentPlan = plan.id === currentPlanId;
|
||||||
const planAction = getPlanAction(plan);
|
const planAction = getPlanAction(plan);
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import { usePaidStatus } from "@/hooks/usePaidStatus";
|
|||||||
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
|
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
import { toUnicode } from "punycode";
|
import { toUnicode } from "punycode";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
import { useUserContext } from "@app/hooks/useUserContext";
|
||||||
|
|
||||||
type AvailableOption = {
|
type AvailableOption = {
|
||||||
domainNamespaceId: string;
|
domainNamespaceId: string;
|
||||||
@@ -97,10 +98,16 @@ export default function DomainPicker({
|
|||||||
warnOnProvidedDomain = false
|
warnOnProvidedDomain = false
|
||||||
}: DomainPickerProps) {
|
}: DomainPickerProps) {
|
||||||
const { env } = useEnvContext();
|
const { env } = useEnvContext();
|
||||||
|
const { user } = useUserContext();
|
||||||
const api = createApiClient({ env });
|
const api = createApiClient({ env });
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const { hasSaasSubscription } = usePaidStatus();
|
const { hasSaasSubscription } = usePaidStatus();
|
||||||
|
|
||||||
|
const requiresPaywall =
|
||||||
|
build === "saas" &&
|
||||||
|
!hasSaasSubscription(tierMatrix[TierFeature.DomainNamespaces]) &&
|
||||||
|
new Date(user.dateCreated) > new Date("2026-04-13");
|
||||||
|
|
||||||
const { data = [], isLoading: loadingDomains } = useQuery(
|
const { data = [], isLoading: loadingDomains } = useQuery(
|
||||||
orgQueries.domains({ orgId })
|
orgQueries.domains({ orgId })
|
||||||
);
|
);
|
||||||
@@ -656,6 +663,7 @@ export default function DomainPicker({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
className="mx-2 rounded-md"
|
className="mx-2 rounded-md"
|
||||||
|
disabled={requiresPaywall}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 mr-3">
|
<div className="flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 mr-3">
|
||||||
<Zap className="h-4 w-4 text-primary" />
|
<Zap className="h-4 w-4 text-primary" />
|
||||||
@@ -696,11 +704,7 @@ export default function DomainPicker({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{build === "saas" &&
|
{requiresPaywall && !hideFreeDomain && (
|
||||||
!hasSaasSubscription(
|
|
||||||
tierMatrix[TierFeature.DomainNamespaces]
|
|
||||||
) &&
|
|
||||||
!hideFreeDomain && (
|
|
||||||
<Card className="mt-3 border-black-500/30 bg-linear-to-br from-black-500/10 via-background to-background overflow-hidden">
|
<Card className="mt-3 border-black-500/30 bg-linear-to-br from-black-500/10 via-background to-background overflow-hidden">
|
||||||
<CardContent className="py-3 px-4">
|
<CardContent className="py-3 px-4">
|
||||||
<div className="flex items-center gap-2.5 text-sm text-muted-foreground">
|
<div className="flex items-center gap-2.5 text-sm text-muted-foreground">
|
||||||
|
|||||||
Reference in New Issue
Block a user