Make paid feature

This commit is contained in:
Owen
2026-04-21 16:52:26 -07:00
parent 38f1387db1
commit 09744cf2f0

View File

@@ -31,6 +31,9 @@ import { createApiClient, formatAxiosError } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext"; import { useEnvContext } from "@app/hooks/useEnvContext";
import { toast } from "@app/hooks/useToast"; import { toast } from "@app/hooks/useToast";
import { orgQueries } from "@app/lib/queries"; import { orgQueries } from "@app/lib/queries";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
interface UptimeAlertSectionProps { interface UptimeAlertSectionProps {
orgId: string; orgId: string;
@@ -49,6 +52,8 @@ export default function UptimeAlertSection({
}: UptimeAlertSectionProps) { }: UptimeAlertSectionProps) {
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { isPaidUser } = usePaidStatus();
const isPaid = isPaidUser(tierMatrix.alertingRules);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [name, setName] = useState(`${siteId ? "Site" : "Resource"} ${startingName} Alert`); const [name, setName] = useState(`${siteId ? "Site" : "Resource"} ${startingName} Alert`);
@@ -207,82 +212,90 @@ export default function UptimeAlertSection({
</CredenzaHeader> </CredenzaHeader>
<CredenzaBody> <CredenzaBody>
<div className="space-y-4"> <div className="space-y-4">
<div className="space-y-2"> <PaidFeaturesAlert tiers={tierMatrix.alertingRules} />
<Label htmlFor="alert-name">Name</Label> <fieldset
<Input disabled={!isPaid}
id="alert-name" className={!isPaid ? "opacity-50 pointer-events-none" : ""}
value={name} >
onChange={(e) => setName(e.target.value)} <div className="space-y-4">
placeholder="Alert name" <div className="space-y-2">
/> <Label htmlFor="alert-name">Name</Label>
</div> <Input
<div className="space-y-2"> id="alert-name"
<Label>Notify Users</Label> value={name}
<TagInput onChange={(e) => setName(e.target.value)}
activeTagIndex={activeUserTagIndex} placeholder="Alert name"
setActiveTagIndex={setActiveUserTagIndex} />
placeholder="Select users..." </div>
size="sm" <div className="space-y-2">
tags={userTags} <Label>Notify Users</Label>
setTags={(newTags) => { <TagInput
const next = activeTagIndex={activeUserTagIndex}
typeof newTags === "function" setActiveTagIndex={setActiveUserTagIndex}
? newTags(userTags) placeholder="Select users..."
: newTags; size="sm"
setUserTags(next as Tag[]); tags={userTags}
}} setTags={(newTags) => {
enableAutocomplete const next =
autocompleteOptions={allUsers} typeof newTags === "function"
restrictTagsToAutocompleteOptions ? newTags(userTags)
allowDuplicates={false} : newTags;
sortTags setUserTags(next as Tag[]);
/> }}
</div> enableAutocomplete
<div className="space-y-2"> autocompleteOptions={allUsers}
<Label>Notify Roles</Label> restrictTagsToAutocompleteOptions
<TagInput allowDuplicates={false}
activeTagIndex={activeRoleTagIndex} sortTags
setActiveTagIndex={setActiveRoleTagIndex} />
placeholder="Select roles..." </div>
size="sm" <div className="space-y-2">
tags={roleTags} <Label>Notify Roles</Label>
setTags={(newTags) => { <TagInput
const next = activeTagIndex={activeRoleTagIndex}
typeof newTags === "function" setActiveTagIndex={setActiveRoleTagIndex}
? newTags(roleTags) placeholder="Select roles..."
: newTags; size="sm"
setRoleTags(next as Tag[]); tags={roleTags}
}} setTags={(newTags) => {
enableAutocomplete const next =
autocompleteOptions={allRoles} typeof newTags === "function"
restrictTagsToAutocompleteOptions ? newTags(roleTags)
allowDuplicates={false} : newTags;
sortTags setRoleTags(next as Tag[]);
/> }}
</div> enableAutocomplete
<div className="space-y-2"> autocompleteOptions={allRoles}
<Label>Additional Emails</Label> restrictTagsToAutocompleteOptions
<TagInput allowDuplicates={false}
activeTagIndex={activeEmailTagIndex} sortTags
setActiveTagIndex={setActiveEmailTagIndex} />
placeholder="Enter email addresses..." </div>
size="sm" <div className="space-y-2">
tags={emailTags} <Label>Additional Emails</Label>
setTags={(newTags) => { <TagInput
const next = activeTagIndex={activeEmailTagIndex}
typeof newTags === "function" setActiveTagIndex={setActiveEmailTagIndex}
? newTags(emailTags) placeholder="Enter email addresses..."
: newTags; size="sm"
setEmailTags(next as Tag[]); tags={emailTags}
}} setTags={(newTags) => {
allowDuplicates={false} const next =
sortTags typeof newTags === "function"
validateTag={(tag) => ? newTags(emailTags)
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(tag) : newTags;
} setEmailTags(next as Tag[]);
delimiterList={[",", "Enter"]} }}
/> allowDuplicates={false}
</div> sortTags
validateTag={(tag) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(tag)
}
delimiterList={[",", "Enter"]}
/>
</div>
</div>
</fieldset>
</div> </div>
</CredenzaBody> </CredenzaBody>
<CredenzaFooter> <CredenzaFooter>
@@ -292,7 +305,7 @@ export default function UptimeAlertSection({
<Button <Button
onClick={handleSubmit} onClick={handleSubmit}
loading={loading} loading={loading}
disabled={loading} disabled={loading || !isPaid}
> >
Create Alert Create Alert
</Button> </Button>