Expand AITURK Turkish settings and desktop surfaces for beta 5

This commit is contained in:
yilsem committed 2026-09-06 05:03:32 +03:00
1 parent 237d1e2060
commit 5e76f58637
108 files changed
+6675 -1034

No files matched your search

@@ -7,6 +7,7 @@ import { cn } from '@/lib/utils'
import { Pill } from '../primitives'
import { type BillingCopy, DEFAULT_BILLING_COPY, useBillingCopy } from './copy'
import { BillingRefusalInline } from './inline-feedback'
import { TierArt } from './tier-art'
import { type BillingPlanTierView, formatBillingDate, formatMonthlyCreditsDelta } from './use-billing-state'
@@ -16,9 +17,13 @@ type DowngradeFlow = ReturnType<typeof useDowngradeFlow>
// The human sentence for the panel body, derived purely from the phase. `null` while
// a refusal is the only thing to show (BillingRefusalInline renders that separately).
function previewMessage(phase: DowngradePhase, fallbackTierName: string): null | string {
function previewMessage(
phase: DowngradePhase,
fallbackTierName: string,
copy: BillingCopy = DEFAULT_BILLING_COPY
): null | string {
if (phase.kind === 'previewing') {
return 'Checking this change…'
return copy.checkingChange
}
if (phase.kind === 'previewFailed') {
@@ -27,28 +32,27 @@ function previewMessage(phase: DowngradePhase, fallbackTierName: string): null |
const { preview } = phase
const targetName = preview.target_tier_name ?? fallbackTierName
const creditsDelta = formatMonthlyCreditsDelta(preview.monthly_credits_delta)
const creditsDelta = formatMonthlyCreditsDelta(preview.monthly_credits_delta, copy)
switch (preview.effect) {
case 'blocked':
return preview.reason ?? 'That change cannot be made here.'
return preview.reason ?? copy.cannotChange
case 'no_op':
return `You are already on ${targetName} — nothing to change.`
return copy.alreadyPlan(targetName)
case 'scheduled':
return (
`Change to ${targetName} — takes effect ${formatBillingDate(preview.effective_at)}. No charge now; ` +
`you keep your current plan until then.${creditsDelta ? ` Monthly credits change: ${creditsDelta}.` : ''}`
)
return copy.scheduledChange(targetName, formatBillingDate(preview.effective_at, copy), creditsDelta)
default:
return 'This change cannot be scheduled here.'
return copy.cannotSchedule
}
}
// The in-card preview → confirm panel for a downgrade (mirrors the TUI confirm flow).
function DowngradeConfirm({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierView }) {
const copy = useBillingCopy()
const active = flow.active
const panelRef = useRef<HTMLDivElement>(null)
const open = active?.target.tierId === tier.tierId
@@ -69,7 +73,7 @@ function DowngradeConfirm({ flow, tier }: { flow: DowngradeFlow; tier: BillingPl
const captionCn = 'text-[length:var(--conversation-caption-font-size)] text-(--ui-text-tertiary)'
const refusal = phase.kind === 'previewFailed' || phase.kind === 'scheduleFailed' ? phase.refusal : null
const busy = phase.kind === 'previewing' || phase.kind === 'scheduling'
const message = previewMessage(phase, tier.name)
const message = previewMessage(phase, tier.name, copy)
const canConfirm =
(phase.kind === 'ready' && phase.preview.effect === 'scheduled') ||
@@ -91,19 +95,19 @@ function DowngradeConfirm({ flow, tier }: { flow: DowngradeFlow; tier: BillingPl
<div className="flex min-w-0 flex-wrap items-center gap-2">
{phase.kind === 'previewFailed' ? (
<Button disabled={busy} onClick={flow.retryPreview} size="sm" type="button">
Try again
{copy.tryAgain}
</Button>
) : canConfirm ? (
<Button disabled={busy} onClick={() => void flow.confirm()} size="sm" type="button">
{phase.kind === 'scheduling'
? 'Scheduling…'
? copy.scheduling
: phase.kind === 'scheduleFailed'
? 'Try again'
: 'Confirm downgrade'}
? copy.tryAgain
: copy.confirmDowngrade}
</Button>
) : null}
<Button disabled={busy} onClick={flow.cancel} size="sm" type="button" variant="outline">
Cancel
{copy.cancel}
</Button>
</div>
</div>
@@ -111,6 +115,8 @@ function DowngradeConfirm({ flow, tier }: { flow: DowngradeFlow; tier: BillingPl
}
function PlanCard({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierView }) {
const copy = useBillingCopy()
const isCurrent = tier.state === 'current'
const confirming = flow.active?.target.tierId === tier.tierId
const cardRef = useRef<HTMLDivElement>(null)
@@ -143,7 +149,8 @@ function PlanCard({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierVi
{tier.name}
</div>
<div className="text-[length:var(--conversation-caption-font-size)] text-(--ui-text-tertiary)">
{tier.priceDisplay}/mo
{tier.priceDisplay}
{copy.monthSuffix}
</div>
</div>
</div>
@@ -155,9 +162,9 @@ function PlanCard({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierVi
)}
<div className="mt-auto min-w-0 pt-1">
{isCurrent && <Pill tone="primary">Current plan</Pill>}
{isCurrent && <Pill tone="primary">{copy.currentPlan}</Pill>}
{tier.state === 'scheduled' && <Pill>Scheduled</Pill>}
{tier.state === 'scheduled' && <Pill>{copy.scheduled}</Pill>}
{tier.state === 'upgrade' && (
<Button
@@ -183,7 +190,7 @@ function PlanCard({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierVi
type="button"
variant="outline"
>
Downgrade
{copy.downgrade}
</Button>
))}
</div>
@@ -192,6 +199,8 @@ function PlanCard({ flow, tier }: { flow: DowngradeFlow; tier: BillingPlanTierVi
}
export function BillingPlansView({ onBack, tiers }: { onBack: () => void; tiers: BillingPlanTierView[] }) {
const copy = useBillingCopy()
// A scheduled downgrade lands the user back on the overview, where the plan card
// now shows the pending state with its undo.
const flow = useDowngradeFlow({ onScheduled: onBack })
@@ -200,7 +209,7 @@ export function BillingPlansView({ onBack, tiers }: { onBack: () => void; tiers:
<div className="@container">
<div className="mb-2.5 flex items-center gap-2 pt-2 text-[length:var(--conversation-text-font-size)] font-medium">
<Button
aria-label="Back to billing"
aria-label={copy.backBilling}
className="size-7 p-0 text-(--ui-text-tertiary)"
disabled={flow.mutating}
onClick={onBack}
@@ -210,7 +219,7 @@ export function BillingPlansView({ onBack, tiers }: { onBack: () => void; tiers:
>
<ChevronLeft className="size-4" />
</Button>
<span>Plans</span>
<span>{copy.plans}</span>
</div>
{tiers.length > 0 ? (
@@ -221,7 +230,7 @@ export function BillingPlansView({ onBack, tiers }: { onBack: () => void; tiers:
</div>
) : (
<div className="rounded-xl bg-(--ui-bg-quaternary) p-4 text-[length:var(--conversation-caption-font-size)] text-(--ui-text-tertiary)">
No plans are available to change to right now.
{copy.noPlans}
</div>
)}
</div>