Polish mobile and web experience
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user