Fix Live Activity lock screen rendering and polish multi-account auth.
Flatten widget layouts and use system colors so banner and expanded regions render on vibrant lock screens; migrate auth sessions per account to prevent double sign-in; scope app lock PIN to accounts; default clock description to "Clock In"; add architecture docs and deferred form validation on auth screens. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import { fonts, spacing } from "@/constants/theme";
|
||||
import { useAppTheme } from "@/contexts/ThemeContext";
|
||||
import { formatCurrency } from "@/lib/format";
|
||||
import { getInvoiceStatus } from "@/lib/invoice-status";
|
||||
import { validateLineItems } from "@/lib/form-validation";
|
||||
import { useTabBarScrollPadding } from "@/lib/tab-bar-insets";
|
||||
import type { ThemeColors } from "@/lib/theme-palette";
|
||||
import { useThemedStyles } from "@/lib/use-themed-styles";
|
||||
@@ -100,6 +101,8 @@ export default function InvoiceEditScreen() {
|
||||
const taxAmount = subtotal * (taxRate / 100);
|
||||
const total = subtotal + taxAmount;
|
||||
const currency = invoice?.currency ?? "USD";
|
||||
const lineItemsError = validateLineItems(items);
|
||||
const canSave = !lineItemsError;
|
||||
|
||||
if (!id) {
|
||||
return <LoadingScreen message="Invalid invoice" />;
|
||||
@@ -170,6 +173,7 @@ export default function InvoiceEditScreen() {
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
if (!canSave) return;
|
||||
setError(null);
|
||||
|
||||
const parsedItems: Array<{
|
||||
@@ -180,25 +184,11 @@ export default function InvoiceEditScreen() {
|
||||
}> = [];
|
||||
|
||||
for (const item of items) {
|
||||
const hours = Number(item.hours);
|
||||
const rate = Number(item.rate);
|
||||
if (!item.description.trim()) {
|
||||
setError("Each line needs a description");
|
||||
return;
|
||||
}
|
||||
if (Number.isNaN(hours) || hours < 0) {
|
||||
setError("Hours must be a valid number");
|
||||
return;
|
||||
}
|
||||
if (Number.isNaN(rate) || rate < 0) {
|
||||
setError("Rate must be a valid number");
|
||||
return;
|
||||
}
|
||||
parsedItems.push({
|
||||
date: item.date,
|
||||
description: item.description.trim(),
|
||||
hours,
|
||||
rate,
|
||||
hours: Number(item.hours),
|
||||
rate: Number(item.rate),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -274,10 +264,16 @@ export default function InvoiceEditScreen() {
|
||||
</View>
|
||||
</Card>
|
||||
|
||||
{lineItemsError ? <Text style={styles.error}>{lineItemsError}</Text> : null}
|
||||
{error ? <Text style={styles.error}>{error}</Text> : null}
|
||||
|
||||
<View style={styles.actions}>
|
||||
<Button title="Save changes" loading={updateInvoice.isPending} onPress={handleSave} />
|
||||
<Button
|
||||
title="Save changes"
|
||||
loading={updateInvoice.isPending}
|
||||
disabled={!canSave}
|
||||
onPress={handleSave}
|
||||
/>
|
||||
{status !== "paid" ? (
|
||||
<Button
|
||||
title={status === "draft" ? "Send invoice" : "Resend invoice"}
|
||||
|
||||
Reference in New Issue
Block a user