Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM, PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source files covering clients, berths, interests/pipeline, documents/EOI, expenses/invoices, email, notifications, dashboard, admin, and client portal. CI/CD via Gitea Actions with Docker builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
40
src/app/(dashboard)/[portSlug]/expenses/[id]/page.tsx
Normal file
40
src/app/(dashboard)/[portSlug]/expenses/[id]/page.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
|
||||
import { ExpenseDetail } from '@/components/expenses/expense-detail';
|
||||
import { ExpenseFormDialog } from '@/components/expenses/expense-form-dialog';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { apiFetch } from '@/lib/api/client';
|
||||
import type { ExpenseRow } from '@/components/expenses/expense-columns';
|
||||
|
||||
export default function ExpenseDetailPage() {
|
||||
const params = useParams<{ portSlug: string; id: string }>();
|
||||
const router = useRouter();
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
|
||||
const { data } = useQuery<{ data: ExpenseRow }>({
|
||||
queryKey: ['expenses', params.id],
|
||||
queryFn: () => apiFetch(`/api/v1/expenses/${params.id}`),
|
||||
enabled: !!params.id,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<ExpenseDetail
|
||||
expenseId={params.id}
|
||||
onEdit={() => setEditOpen(true)}
|
||||
onArchived={() => router.push(`/${params.portSlug}/expenses`)}
|
||||
/>
|
||||
|
||||
{data?.data && (
|
||||
<ExpenseFormDialog
|
||||
open={editOpen}
|
||||
onOpenChange={setEditOpen}
|
||||
expense={data.data}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user