feat(mobile): touch up new-invoice + scan-receipt forms

- new invoice: push "New Invoice" to mobile topbar, hide the
    redundant inline back+title row on mobile.
  - scan receipt: dedicated "Take photo" primary button on mobile
    (uses input capture="environment" to open the camera directly)
    plus "Choose from library" secondary. Drop-zone framing kept on
    desktop. Push "Scan Receipt" title to mobile topbar.

Both forms now take their entity title from the topbar and free up
real-estate at the top for actual content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Ciaccio
2026-05-01 16:06:09 +02:00
parent a653c8e039
commit d080bc52fa
2 changed files with 67 additions and 33 deletions

View File

@@ -1,12 +1,14 @@
'use client';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation } from '@tanstack/react-query';
import { ChevronLeft, ChevronRight, Check, Loader2 } from 'lucide-react';
import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
@@ -46,6 +48,12 @@ export default function NewInvoicePage() {
const [step, setStep] = useState(1);
const { setChrome } = useMobileChrome();
useEffect(() => {
setChrome({ title: 'New Invoice', showBackButton: true });
return () => setChrome({ title: null, showBackButton: false });
}, [setChrome]);
const methods = useForm<CreateInvoiceInput>({
resolver: zodResolver(createInvoiceSchema),
defaultValues: {
@@ -117,8 +125,8 @@ export default function NewInvoicePage() {
return (
<div className="max-w-2xl mx-auto space-y-6">
{/* Header */}
<div className="flex items-center gap-3">
{/* Header — desktop only; mobile gets the title from the topbar */}
<div className="hidden sm:flex items-center gap-3">
<Button variant="ghost" size="sm" onClick={() => router.push(`/${portSlug}/invoices`)}>
<ChevronLeft className="h-4 w-4" />
</Button>