fix(uat): batch — timeline overshoot, name-sync, reset-password, dashboard cleanup, queue/seed hygiene + alpha UAT findings doc
UAT findings landed across the last few Playwright + React Grab passes; single grouped commit so the index doesn't fragment into 30 one-liners. User & auth: - `user-settings`: name now updates the avatar + topbar menu after save (was reading stale session). - `me/password-reset`: 3 bugs (token validation, error response shape, redirect chain). - Admin user permission-overrides route honours the same envelope as the rest of the admin surface. Dashboard: - Removed obsolete `revenue-breakdown-chart` + `dashboard-widgets-card` (replaced by the customisable widget grid). - Strip `revenue_breakdown` from analytics route + use-analytics + service + integration test so nothing renders an empty card. - Activity log timeline overshoot fix (`interest-timeline` + `entity-activity-feed`). - Tightened tiles: active-deals, berth-heat-widget, pipeline-value, kpi-tile. - `dev-mode-banner`: derive dismissed state synchronously instead of via an effect (set-state-in-effect lint rule). Forms & lists (assorted polish): - client / company / yacht / interest / reminder forms — validation + empty-state copy + tab transitions. - companies/yachts list tweaks; berth recommender panel; qualification checklist; supplemental info request button. Infra & misc: - Queue workers (ai / email / notifications) — log shape + per-job timeout consistency. - Auth / brochures / users schema small adjustments; seeds reflect permissions matrix changes. - Scan shell + scanner manifest + AI admin page small fixes. - `next.config.transpilePackages` adds `echarts`/`zrender`/`echarts-for-react` (recommended config from echarts-for-react inside Next). Docs: - `docs/superpowers/audits/alpha-uat-master.md` — single rolling cross-cutting UAT findings doc (per CLAUDE.md convention). - `docs/BACKLOG.md`: dashboard stats cards (§I) + activity-log normalization (§J). - 2026-05-18 audit log updated with this batch. - `CLAUDE.md` — small manual UAT scaffold notes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,9 +75,17 @@ interface CompanyFormProps {
|
||||
billingEmail: string | null;
|
||||
notes: string | null;
|
||||
};
|
||||
/**
|
||||
* Optional initial values for the create flow — used by the global
|
||||
* command-search quick-create ("New company 'matthew'" → lands on
|
||||
* `/companies?create=1&prefill_name=matthew`). Ignored in edit mode.
|
||||
*/
|
||||
prefill?: {
|
||||
name?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function CompanyForm({ open, onOpenChange, company }: CompanyFormProps) {
|
||||
export function CompanyForm({ open, onOpenChange, company, prefill }: CompanyFormProps) {
|
||||
const queryClient = useQueryClient();
|
||||
const router = useRouter();
|
||||
const isEdit = !!company;
|
||||
@@ -141,10 +149,10 @@ export function CompanyForm({ open, onOpenChange, company }: CompanyFormProps) {
|
||||
tagIds: [],
|
||||
});
|
||||
} else if (!company && open) {
|
||||
reset({ name: '', status: 'active', tagIds: [] });
|
||||
reset({ name: prefill?.name ?? '', status: 'active', tagIds: [] });
|
||||
}
|
||||
setFormError(null);
|
||||
}, [company, open, reset]);
|
||||
}, [company, open, reset, prefill]);
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: async (data: CreateCompanyInput) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useParams, useSearchParams } from 'next/navigation';
|
||||
import { Plus, Archive, Tag as TagIcon, TagsIcon } from 'lucide-react';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { toast } from 'sonner';
|
||||
@@ -49,6 +49,16 @@ export function CompanyList() {
|
||||
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
useCreateFromUrl(() => setCreateOpen(true));
|
||||
|
||||
// Quick-create from the global command-search lands here with
|
||||
// `?create=1&prefill_name=…`. Hydrate the company-form's name field
|
||||
// so the rep doesn't retype.
|
||||
const searchParams = useSearchParams();
|
||||
const createPrefill = useMemo(() => {
|
||||
const name = searchParams?.get('prefill_name');
|
||||
return name ? { name } : undefined;
|
||||
}, [searchParams]);
|
||||
|
||||
const [editCompany, setEditCompany] = useState<CompanyRow | null>(null);
|
||||
const [archiveCompany, setArchiveCompany] = useState<CompanyRow | null>(null);
|
||||
const [tagDialog, setTagDialog] = useState<{ ids: string[]; mode: 'add' | 'remove' } | null>(
|
||||
@@ -274,7 +284,7 @@ export function CompanyList() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<CompanyForm open={createOpen} onOpenChange={setCreateOpen} />
|
||||
<CompanyForm open={createOpen} onOpenChange={setCreateOpen} prefill={createPrefill} />
|
||||
|
||||
{editCompany && (
|
||||
<CompanyForm
|
||||
|
||||
Reference in New Issue
Block a user