Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c775ef5
Update design system palette and components
cursoragent Jan 30, 2026
7ffb124
Restyle recipients list and detail views
cursoragent Jan 30, 2026
7e492f6
Restyle recipient editor and profile settings
cursoragent Jan 30, 2026
5357d90
Refine marketing homepage layout
cursoragent Jan 30, 2026
3f1b63a
Remove unused import in recipient editor
cursoragent Jan 30, 2026
ab14ffc
Style auth and subscription flows
cursoragent Jan 30, 2026
a5c366d
Handle phone identifiers flexibly
cursoragent Jan 30, 2026
a30f079
Fix 5 bugs: forgot-password schema mismatch, missing outlet context, …
cursoragent Jan 30, 2026
2c102ae
Update e2e selectors for new auth UI
cursoragent Jan 30, 2026
f8851cd
Fix e2e expectations for phone flows
cursoragent Jan 30, 2026
6718db5
Fix design system bugs: pricing consistency, non-functional CTA, miss…
cursoragent Jan 30, 2026
cff764e
Stabilize onboarding and send e2e tests
cursoragent Jan 30, 2026
b5efcdf
Stabilize send message e2e test
cursoragent Jan 30, 2026
67486d9
Wait for message creation in send test
cursoragent Jan 30, 2026
e9cff60
Fix: resolve three bugs - phone normalization, unused import, and sub…
cursoragent Jan 30, 2026
3dfa3c3
Fix: resolve critical bugs in form handling and ButtonLink component
cursoragent Jan 30, 2026
a6ad36f
Fix: resolve TypeScript error and critical bugs
cursoragent Jan 30, 2026
8d2a463
Fix: address relevant comments and update test to match phone normali…
cursoragent Jan 30, 2026
efee4f5
Fix: duplicate check normalization must match registration logic
cursoragent Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 22 additions & 13 deletions app/components/forms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from 'input-otp'
import React, { useId } from 'react'
import { Checkbox, type CheckboxProps } from './ui/checkbox.tsx'
import { Icon } from './ui/icon.tsx'
import {
InputOTP,
InputOTPGroup,
Expand All @@ -30,7 +31,7 @@ export function ErrorList({
return (
<ul id={id} className="flex flex-col gap-1">
{errorsToRender.map((e) => (
<li key={e} className="text-[10px] text-foreground-destructive">
<li key={e} className="text-xs font-medium text-foreground-destructive">
{e}
</li>
))}
Expand Down Expand Up @@ -61,7 +62,7 @@ export function Field({
aria-describedby={errorId}
{...inputProps}
/>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<div className="min-h-[24px] px-4 pb-2 pt-2">
{errorId ? <ErrorList id={errorId} errors={errors} /> : null}
</div>
</div>
Expand All @@ -85,14 +86,22 @@ export function SelectField({
return (
<div className={className}>
<Label htmlFor={id} {...labelProps} />
<select
id={id}
aria-invalid={errorId ? true : undefined}
aria-describedby={errorId}
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid]:border-input-invalid"
{...selectProps}
/>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<div className="relative">
<select
id={id}
aria-invalid={errorId ? true : undefined}
aria-describedby={errorId}
className="flex h-12 w-full appearance-none rounded-full border border-input bg-card px-4 pr-10 text-sm font-medium text-foreground shadow-sm transition-colors placeholder:text-muted-secondary-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground aria-[invalid]:border-input-invalid aria-[invalid]:text-foreground-destructive aria-[invalid]:focus-visible:ring-foreground-destructive"
{...selectProps}
/>
<Icon
name="chevron-down"
size="sm"
aria-hidden="true"
className="pointer-events-none absolute right-4 top-1/2 -translate-y-1/2 text-muted-secondary-foreground"
/>
</div>
<div className="min-h-[24px] px-4 pb-2 pt-2">
{errorId ? <ErrorList id={errorId} errors={errors} /> : null}
</div>
</div>
Expand Down Expand Up @@ -141,7 +150,7 @@ export function OTPField({
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<div className="min-h-[24px] px-4 pb-2 pt-2">
{errorId ? <ErrorList id={errorId} errors={errors} /> : null}
</div>
</div>
Expand Down Expand Up @@ -171,7 +180,7 @@ export function TextareaField({
aria-describedby={errorId}
{...textareaProps}
/>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<div className="min-h-[24px] px-4 pb-2 pt-2">
{errorId ? <ErrorList id={errorId} errors={errors} /> : null}
</div>
</div>
Expand Down Expand Up @@ -234,7 +243,7 @@ export function CheckboxField({
className="self-center text-body-xs text-muted-foreground"
/>
</div>
<div className="px-4 pb-3 pt-1">
<div className="px-4 pb-2 pt-2">
{errorId ? <ErrorList id={errorId} errors={errors} /> : null}
</div>
</div>
Expand Down
32 changes: 16 additions & 16 deletions app/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ import * as React from 'react'
import { cn } from '#app/utils/misc.tsx'

const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium outline-none ring-ring ring-offset-2 ring-offset-background transition-colors focus-within:ring-2 focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
'inline-flex items-center justify-center gap-2 rounded-full text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/80',
default: 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/80',
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
'border border-border bg-card text-foreground hover:bg-muted',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
'border border-border bg-transparent text-foreground hover:bg-muted',
ghost: 'text-foreground hover:bg-muted',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
wide: 'px-24 py-5',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
pill: 'px-12 py-3 leading-3',
icon: 'h-10 w-10',
default: 'h-12 px-6',
wide: 'h-12 px-14',
sm: 'h-10 px-4 text-xs',
lg: 'h-14 px-8 text-base',
pill: 'h-10 px-8 text-sm',
icon: 'h-10 w-10 p-0',
},
icon: {
true: 'flex h-10 w-10 items-center justify-center rounded-full p-2',
false: 'px-6 py-2',
true: 'h-10 w-10 rounded-full p-2',
false: '',
},
},
defaultVariants: {
Expand Down Expand Up @@ -62,13 +62,13 @@ Button.displayName = 'Button'

export function ButtonLink({
variant,

size,
icon,
className,
...props
}: LinkProps & VariantProps<typeof buttonVariants>) {
return (
<Link className={buttonVariants({ variant, icon, className })} {...props} />
<Link className={buttonVariants({ variant, size, icon, className })} {...props} />
)
}

Expand Down
6 changes: 3 additions & 3 deletions app/components/ui/input-otp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const InputOTPGroup = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn('flex items-center', className)} {...props} />
<div ref={ref} className={cn('flex items-center gap-2', className)} {...props} />
))
InputOTPGroup.displayName = 'InputOTPGroup'

Expand All @@ -40,8 +40,8 @@ const InputOTPSlot = React.forwardRef<
<div
ref={ref}
className={cn(
'relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-base transition-all first:rounded-l-md first:border-l last:rounded-r-md md:text-sm',
isActive && 'z-10 ring-2 ring-ring ring-offset-background',
'relative flex h-12 w-12 items-center justify-center rounded-2xl border border-input bg-card text-base font-medium text-foreground shadow-sm transition-colors',
isActive && 'z-10 border-ring ring-2 ring-ring',
className,
)}
{...props}
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid]:border-input-invalid md:text-sm',
'flex h-12 w-full rounded-full border border-input bg-card px-4 text-sm font-medium text-foreground shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-semibold placeholder:text-muted-secondary-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground aria-[invalid]:border-input-invalid aria-[invalid]:text-foreground-destructive aria-[invalid]:focus-visible:ring-foreground-destructive',
className,
)}
ref={ref}
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as React from 'react'
import { cn } from '#app/utils/misc.tsx'

const labelVariants = cva(
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
'text-xs font-semibold uppercase leading-none tracking-[0.08em] text-muted-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
)

const Label = React.forwardRef<
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
return (
<textarea
className={cn(
'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 aria-[invalid]:border-input-invalid md:text-sm',
'flex min-h-[120px] w-full rounded-3xl border border-input bg-card px-4 py-3 text-sm font-medium text-foreground shadow-sm transition-colors placeholder:text-muted-secondary-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground aria-[invalid]:border-input-invalid aria-[invalid]:text-foreground-destructive aria-[invalid]:focus-visible:ring-foreground-destructive',
className,
)}
ref={ref}
Expand Down
Loading
Loading