feat(quotes): filter list to the logged-in rep's own quotes
This commit is contained in:
parent
defa481661
commit
8faa4437b6
1 changed files with 16 additions and 4 deletions
|
|
@ -32,6 +32,8 @@ import {
|
|||
import { toast } from "sonner";
|
||||
import { cn } from "@/lib/utils";
|
||||
import getPocketBase from "@/lib/pocketbase";
|
||||
import { useAuth } from "@/components/auth-provider";
|
||||
import { isRepUser } from "@/lib/rep-visibility";
|
||||
import {
|
||||
getQuoteItems,
|
||||
fetchQuoteItemCounts,
|
||||
|
|
@ -140,6 +142,7 @@ const AGED_STATUSES: ReadonlySet<string> = new Set(["new", "claimed"]);
|
|||
|
||||
export default function QuotesPage() {
|
||||
const router = useRouter();
|
||||
const { user } = useAuth();
|
||||
const [quotes, setQuotes] = useState<Quote[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
|
|
@ -439,6 +442,15 @@ export default function QuotesPage() {
|
|||
return map;
|
||||
}, [users]);
|
||||
|
||||
// Rep-scoped UI filter — same rationale as the Orders page (see
|
||||
// src/lib/rep-visibility.ts). Quotes only carry rep via the
|
||||
// customer relation (no denormalized text field like orders.rep).
|
||||
const visibleQuotes = useMemo(() => {
|
||||
const userType = (user as { user_type?: string[] } | null)?.user_type;
|
||||
if (!user || !isRepUser(userType)) return quotes;
|
||||
return quotes.filter((quote) => quote.expand?.customer?.rep === user.id);
|
||||
}, [quotes, user]);
|
||||
|
||||
/**
|
||||
* Toggle a row's expanded state. The first time a row opens we kick
|
||||
* off a `getQuoteItems(id)` fetch; subsequent toggles use the cache.
|
||||
|
|
@ -867,7 +879,7 @@ export default function QuotesPage() {
|
|||
},
|
||||
},
|
||||
]}
|
||||
data={quotes}
|
||||
data={visibleQuotes}
|
||||
loading={loading}
|
||||
error={error}
|
||||
// Placeholder lists every surface the pushdown actually hits
|
||||
|
|
@ -898,7 +910,7 @@ export default function QuotesPage() {
|
|||
"text-xs whitespace-nowrap",
|
||||
loading
|
||||
? "text-muted-foreground/60"
|
||||
: quotes.length === 0
|
||||
: visibleQuotes.length === 0
|
||||
? "text-warn font-medium"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
|
|
@ -906,11 +918,11 @@ export default function QuotesPage() {
|
|||
>
|
||||
{loading ? (
|
||||
<>Searching…</>
|
||||
) : quotes.length === 0 ? (
|
||||
) : visibleQuotes.length === 0 ? (
|
||||
<>0 matches for “{searchInput.trim()}”</>
|
||||
) : (
|
||||
<>
|
||||
{quotes.length} match{quotes.length === 1 ? "" : "es"} for{" "}
|
||||
{visibleQuotes.length} match{visibleQuotes.length === 1 ? "" : "es"} for{" "}
|
||||
<span className="font-medium text-foreground">
|
||||
“{searchInput.trim()}”
|
||||
</span>
|
||||
|
|
|
|||
Loading…
Reference in a new issue