Update commercial use trial wording

This commit is contained in:
Gregory Schier
2025-11-09 07:07:18 -08:00
parent 554e632c19
commit 9eddf716e1
4 changed files with 77 additions and 48 deletions

View File

@@ -10,6 +10,7 @@ import { Button } from '../core/Button';
import { Icon } from '../core/Icon';
import { Link } from '../core/Link';
import { PlainInput } from '../core/PlainInput';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
import { LocalImage } from '../LocalImage';
@@ -34,43 +35,56 @@ function SettingsLicenseCmp() {
<div className="flex flex-col gap-6 max-w-xl">
{check.data?.type === 'commercial_use' ? (
<Banner color="success">Your license is active 🥳</Banner>
) : check.data?.type == 'trialing' ? (
<Banner color="info" className="flex flex-col gap-3 max-w-lg">
<p>
<strong>
{pluralizeCount('day', differenceInDays(check.data.end, new Date()))} remaining
</strong>{' '}
on your commercial-use trial
</p>
</Banner>
) : check.data?.type == 'personal_use' ? (
<Banner color="notice" className="flex flex-col gap-3 max-w-lg">
<p>You are able to use Yaak for personal use only</p>
</Banner>
) : null}
{check.data?.type !== 'commercial_use' && (
<div className="grid grid-cols-[auto_minmax(0,1fr)] gap-6 items-center my-3 ">
<LocalImage src="static/greg.jpeg" className="rounded-full h-20 w-20" />
<div className="flex flex-col gap-2">
<h2 className="text-lg font-bold">Hey, I&apos;m Greg 👋🏼</h2>
<p>
Yaak is free for personal projects and learning.{' '}
{check.data?.type === 'trialing' ? 'Once your trial ends, a ' : 'A '}
license will be required for work or commercial use.
</p>
<p>
) : check.data?.type === 'trialing' ? (
<Banner color="info" className="@container flex items-center gap-x-5 max-w-xl">
<LocalImage src="static/greg.jpeg" className="hidden @sm:block rounded-full h-14 w-14" />
<p className="w-full">
<strong>{pluralizeCount('day', differenceInDays(check.data.end, new Date()))}</strong>{' '}
left to evaluate Yaak for commercial use.
<br />
<span className="opacity-50">Personal use is always free, forever.</span>
<Separator className="my-2" />
<div className="flex flex-wrap items-center gap-x-2 text-sm text-notice">
<Link noUnderline href="mailto:support@yaak.app">
Contact Support
</Link>
<Icon icon="dot" size="sm" color="secondary" />
<Link
noUnderline
href={`https://yaak.app/pricing?s=learn&t=${check.data?.type ?? ''}`}
className="text-sm text-notice opacity-80 hover:opacity-100"
>
Learn More
</Link>
</p>
</div>
</div>
)}
</div>
</p>
</Banner>
) : check.data?.type === 'personal_use' ? (
<Banner color="notice" className="@container flex items-center gap-x-5 max-w-xl">
<LocalImage src="static/greg.jpeg" className="hidden @sm:block rounded-full h-14 w-14" />
<p className="w-full">
Your commercial-use trial has ended.
<br />
<span className="opacity-50">
You can continue using Yaak for personal use free, forever.
<br />
A license is required for commercial use.
</span>
<Separator className="my-2" />
<div className="flex flex-wrap items-center gap-x-2 text-sm text-notice">
<Link noUnderline href="mailto:support@yaak.app">
Contact Support
</Link>
<Icon icon="dot" size="sm" color="secondary" />
<Link
noUnderline
href={`https://yaak.app/pricing?s=learn&t=${check.data?.type ?? ''}`}
>
Learn More
</Link>
</div>
</p>
</Banner>
) : null}
{check.error && <Banner color="danger">{check.error}</Banner>}
{activate.error && <Banner color="danger">{activate.error}</Banner>}

View File

@@ -12,32 +12,37 @@ interface Props extends HTMLAttributes<HTMLAnchorElement> {
export function Link({ href, children, noUnderline, className, ...other }: Props) {
const isExternal = href.match(/^https?:\/\//);
className = classNames(className, 'relative');
className = classNames(
className,
'relative',
'inline-flex items-center hover:underline group',
!noUnderline && 'underline',
);
if (isExternal) {
const isYaakLink = href.startsWith('https://yaak.app');
let finalHref = href;
if (href.startsWith('https://yaak.app')) {
if (isYaakLink) {
const url = new URL(href);
url.searchParams.set('ref', appInfo.identifier);
finalHref = url.toString();
}
return (
// eslint-disable-next-line react/jsx-no-target-blank
<a
href={finalHref}
target="_blank"
rel="noopener noreferrer"
className={classNames(
className,
'pr-4 inline-flex items-center hover:underline group',
!noUnderline && 'underline',
)}
onClick={(e) => {
e.preventDefault();
}}
rel={isYaakLink ? undefined : 'noopener noreferrer'}
onClick={(e) => e.preventDefault()}
className={className}
{...other}
>
<span className="pr-0.5">{children}</span>
<Icon className="inline absolute right-0.5 top-[0.3em] opacity-70 group-hover:opacity-100" size="xs" icon="external_link" />
<span className="pr-5">{children}</span>
<Icon
className="inline absolute right-0.5 top-[0.3em] opacity-70 group-hover:opacity-100"
size="xs"
icon="external_link"
/>
</a>
);
}

View File

@@ -1,3 +1,4 @@
import type { Color } from '@yaakapp-internal/plugins';
import classNames from 'classnames';
import type { ReactNode } from 'react';
@@ -6,9 +7,10 @@ interface Props {
dashed?: boolean;
className?: string;
children?: ReactNode;
color?: Color;
}
export function Separator({ className, dashed, orientation = 'horizontal', children }: Props) {
export function Separator({ color, className, dashed, orientation = 'horizontal', children }: Props) {
return (
<div role="separator" className={classNames(className, 'flex items-center w-full')}>
{children && (
@@ -16,7 +18,15 @@ export function Separator({ className, dashed, orientation = 'horizontal', child
)}
<div
className={classNames(
'h-0 border-t border-t-border-subtle',
'h-0 border-t opacity-60',
color == null && 'border-border',
color === 'primary' && 'border-primary',
color === 'secondary' && 'border-secondary',
color === 'success' && 'border-success',
color === 'notice' && 'border-notice',
color === 'warning' && 'border-warning',
color === 'danger' && 'border-danger',
color === 'info' && 'border-info',
dashed && 'border-dashed',
orientation === 'horizontal' && 'w-full h-[1px]',
orientation === 'vertical' && 'h-full w-[1px]',

View File

@@ -94,8 +94,8 @@ export function Tooltip({ children, content, tabIndex, size = 'md' }: TooltipPro
ref={triggerRef}
role="button"
aria-describedby={isOpen ? id.current : undefined}
tabIndex={tabIndex ?? 0}
className="flex-grow-0 flex items-center"
tabIndex={tabIndex ?? -1}
className="flex-grow-0 inline-flex items-center"
onClick={handleToggleImmediate}
onMouseEnter={handleOpen}
onMouseLeave={handleClose}