mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-05 19:59:43 +00:00
Properly paywall ui for labels
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||||
|
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
import type { CreateOrEditLabelResponse } from "@server/routers/labels/types";
|
import type { CreateOrEditLabelResponse } from "@server/routers/labels/types";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
@@ -18,6 +20,7 @@ import {
|
|||||||
CredenzaTitle
|
CredenzaTitle
|
||||||
} from "./Credenza";
|
} from "./Credenza";
|
||||||
import { OrgLabelForm } from "./OrgLabelForm";
|
import { OrgLabelForm } from "./OrgLabelForm";
|
||||||
|
import { PaidFeaturesAlert } from "./PaidFeaturesAlert";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
export type CreateOrgLabelDialogProps = {
|
export type CreateOrgLabelDialogProps = {
|
||||||
@@ -35,6 +38,8 @@ export function CreateOrgLabelDialog({
|
|||||||
}: CreateOrgLabelDialogProps) {
|
}: CreateOrgLabelDialogProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const api = createApiClient(useEnvContext());
|
const api = createApiClient(useEnvContext());
|
||||||
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
const canManageLabels = isPaidUser(tierMatrix.labels);
|
||||||
const [isSubmitting, startTransition] = useTransition();
|
const [isSubmitting, startTransition] = useTransition();
|
||||||
|
|
||||||
async function createOrgLabel(data: { name: string; color: string }) {
|
async function createOrgLabel(data: { name: string; color: string }) {
|
||||||
@@ -79,8 +84,11 @@ export function CreateOrgLabelDialog({
|
|||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
|
<PaidFeaturesAlert tiers={tierMatrix.labels} />
|
||||||
<OrgLabelForm
|
<OrgLabelForm
|
||||||
|
disabled={!canManageLabels}
|
||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
|
if (!canManageLabels) return;
|
||||||
startTransition(async () => createOrgLabel(data));
|
startTransition(async () => createOrgLabel(data));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -98,7 +106,7 @@ export function CreateOrgLabelDialog({
|
|||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
form="org-label-form"
|
form="org-label-form"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting || !canManageLabels}
|
||||||
loading={isSubmitting}
|
loading={isSubmitting}
|
||||||
>
|
>
|
||||||
{t("labelCreate")}
|
{t("labelCreate")}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||||
|
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
import type { CreateOrEditLabelResponse } from "@server/routers/labels/types";
|
import type { CreateOrEditLabelResponse } from "@server/routers/labels/types";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
@@ -18,6 +20,7 @@ import {
|
|||||||
CredenzaTitle
|
CredenzaTitle
|
||||||
} from "./Credenza";
|
} from "./Credenza";
|
||||||
import { OrgLabelForm } from "./OrgLabelForm";
|
import { OrgLabelForm } from "./OrgLabelForm";
|
||||||
|
import { PaidFeaturesAlert } from "./PaidFeaturesAlert";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
export type EditOrgLabelDialogProps = {
|
export type EditOrgLabelDialogProps = {
|
||||||
@@ -41,6 +44,8 @@ export function EditOrgLabelDialog({
|
|||||||
}: EditOrgLabelDialogProps) {
|
}: EditOrgLabelDialogProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const api = createApiClient(useEnvContext());
|
const api = createApiClient(useEnvContext());
|
||||||
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
const canManageLabels = isPaidUser(tierMatrix.labels);
|
||||||
const [isSubmitting, startTransition] = useTransition();
|
const [isSubmitting, startTransition] = useTransition();
|
||||||
|
|
||||||
async function editOrgLabel(data: { name: string; color: string }) {
|
async function editOrgLabel(data: { name: string; color: string }) {
|
||||||
@@ -85,9 +90,12 @@ export function EditOrgLabelDialog({
|
|||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
|
<PaidFeaturesAlert tiers={tierMatrix.labels} />
|
||||||
<OrgLabelForm
|
<OrgLabelForm
|
||||||
|
disabled={!canManageLabels}
|
||||||
defaultValue={label}
|
defaultValue={label}
|
||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
|
if (!canManageLabels) return;
|
||||||
startTransition(async () => editOrgLabel(data));
|
startTransition(async () => editOrgLabel(data));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -105,7 +113,7 @@ export function EditOrgLabelDialog({
|
|||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
form="org-label-form"
|
form="org-label-form"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting || !canManageLabels}
|
||||||
loading={isSubmitting}
|
loading={isSubmitting}
|
||||||
>
|
>
|
||||||
{t("labelEdit")}
|
{t("labelEdit")}
|
||||||
|
|||||||
@@ -35,9 +35,14 @@ export type LabelFormData = z.infer<typeof labelFormSchema>;
|
|||||||
export type OrgLabelFormProps = {
|
export type OrgLabelFormProps = {
|
||||||
onSubmit: (data: LabelFormData) => void;
|
onSubmit: (data: LabelFormData) => void;
|
||||||
defaultValue?: LabelFormData;
|
defaultValue?: LabelFormData;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function OrgLabelForm({ onSubmit, defaultValue }: OrgLabelFormProps) {
|
export function OrgLabelForm({
|
||||||
|
onSubmit,
|
||||||
|
defaultValue,
|
||||||
|
disabled = false
|
||||||
|
}: OrgLabelFormProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
|
|
||||||
const colorValues = Object.values(LABEL_COLORS);
|
const colorValues = Object.values(LABEL_COLORS);
|
||||||
@@ -70,9 +75,7 @@ export function OrgLabelForm({ onSubmit, defaultValue }: OrgLabelFormProps) {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>{t("labelNameField")}</FormLabel>
|
<FormLabel>{t("labelNameField")}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input {...field} disabled={disabled} />
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -88,6 +91,7 @@ export function OrgLabelForm({ onSubmit, defaultValue }: OrgLabelFormProps) {
|
|||||||
<Select
|
<Select
|
||||||
onValueChange={field.onChange}
|
onValueChange={field.onChange}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue
|
<SelectValue
|
||||||
@@ -110,7 +114,9 @@ export function OrgLabelForm({ onSubmit, defaultValue }: OrgLabelFormProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span data-name>
|
<span data-name>
|
||||||
{color.charAt(0).toUpperCase() +
|
{color
|
||||||
|
.charAt(0)
|
||||||
|
.toUpperCase() +
|
||||||
color.slice(1)}
|
color.slice(1)}
|
||||||
</span>
|
</span>
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|||||||
Reference in New Issue
Block a user