Polish mobile and web experience

This commit is contained in:
2026-08-17 00:18:55 -04:00
parent 6c74436092
commit 9929d7321d
28 changed files with 835 additions and 688 deletions
+12 -4
View File
@@ -15,7 +15,11 @@ import { Input } from "@/components/ui/Input";
import { fonts, spacing } from "@/constants/theme";
import type { ThemeColors } from "@/lib/theme-palette";
import { useThemedStyles } from "@/lib/use-themed-styles";
import { isRequiredString, parseNonNegativeNumber } from "@/lib/form-validation";
import {
isRequiredString,
parseNonNegativeNumber,
useFieldVisibility,
} from "@/lib/form-validation";
import { api } from "@/lib/trpc";
export type ClientFormValues = {
@@ -71,6 +75,7 @@ export function ClientForm({
const [values, setValues] = useState<ClientFormValues>(emptyValues);
const [fieldError, setFieldError] = useState<string | null>(null);
const { touch, visible, markSubmitted } = useFieldVisibility();
useEffect(() => {
const client = clientQuery.data;
@@ -125,6 +130,7 @@ export function ClientForm({
}
function handleSave() {
markSubmitted();
if (!canSave) return;
const rate = values.defaultHourlyRate.trim()
@@ -199,8 +205,9 @@ export function ClientForm({
label="Name"
value={values.name}
onChangeText={(v) => patch("name", v)}
onBlur={() => touch("name")}
required
error={nameError}
error={visible("name") ? nameError : undefined}
/>
<Input
label="Email"
@@ -247,9 +254,10 @@ export function ClientForm({
label="Default hourly rate"
value={values.defaultHourlyRate}
onChangeText={(v) => patch("defaultHourlyRate", v)}
onBlur={() => touch("defaultHourlyRate")}
keyboardType="decimal-pad"
placeholder="Optional"
error={rateError}
error={visible("defaultHourlyRate") ? rateError : undefined}
/>
<Input
label="Currency"
@@ -260,7 +268,7 @@ export function ClientForm({
/>
</Card>
{fieldError ? <Text style={styles.error}>{fieldError}</Text> : null}
{fieldError ? <Text selectable style={styles.error}>{fieldError}</Text> : null}
<View style={styles.actions}>
<Button