tenant profile
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { Badge } from '@astryxdesign/core/Badge';
|
||||
import { Button } from '@astryxdesign/core/Button';
|
||||
@@ -32,6 +33,9 @@ import { useStockRequests, useStockStatement } from '@/queries/hooks';
|
||||
import { useBranchScope } from '../BranchScope';
|
||||
import { CataloguePanel } from '../CataloguePanel';
|
||||
import { ProductsPanel } from '../ProductsPanel';
|
||||
import { SetupReturnBar } from '@/features/onboarding/SetupReturnBar';
|
||||
import type { StepId } from '@/features/onboarding/onboardingState';
|
||||
import { useLocationProducts } from '@/queries/hooks';
|
||||
import { branchLabel, count, money } from '../format';
|
||||
|
||||
type Tab = 'products' | 'catalogue' | 'stock' | 'requests';
|
||||
@@ -53,10 +57,39 @@ type Tab = 'products' | 'catalogue' | 'stock' | 'requests';
|
||||
*/
|
||||
export function InventoryPage() {
|
||||
const { branches, selected, current, tenantid } = useBranchScope();
|
||||
const [tab, setTab] = useState<Tab>('products');
|
||||
|
||||
/**
|
||||
* The tab comes from the URL, so a link can name one.
|
||||
*
|
||||
* It could not before — the tab was local state seeded with 'products' and
|
||||
* nothing ever read the query string. Setup's "add from the catalogue" link
|
||||
* pointed at `?tab=catalogue` and landed the merchant on Products, which is
|
||||
* the bug that made that step look broken.
|
||||
*/
|
||||
const [params, setParams] = useSearchParams();
|
||||
const asked = params.get('tab');
|
||||
const [tab, setTab] = useState<Tab>(() =>
|
||||
asked === 'catalogue' || asked === 'stock' || asked === 'requests' ? asked : 'products',
|
||||
);
|
||||
|
||||
/* A tab chosen by hand replaces the one in the URL, so a reload or a shared
|
||||
link shows the panel actually being looked at. `replace` because flipping
|
||||
between tabs is not navigation and should not fill up the Back button. */
|
||||
function chooseTab(next: Tab) {
|
||||
setTab(next);
|
||||
const carry = new URLSearchParams(params);
|
||||
carry.set('tab', next);
|
||||
setParams(carry, { replace: true });
|
||||
}
|
||||
|
||||
/* Set when setup sent them here, and it names the step to return to. */
|
||||
const fromSetup = params.get('setup') as StepId | null;
|
||||
const setupProducts = useLocationProducts(tenantid || undefined, undefined, 0, {
|
||||
allBranches: true,
|
||||
});
|
||||
// Owned here so the button can live in the tab row while the drawer it opens
|
||||
// stays inside the panel that uses it.
|
||||
const [isUploading, setUploading] = useState(false);
|
||||
const [isUploading, setUploading] = useState(() => params.get('upload') === '1');
|
||||
|
||||
const requests = useStockRequests(
|
||||
tenantid ? { tenantid, locationid: selected ?? undefined } : undefined,
|
||||
@@ -69,6 +102,12 @@ export function InventoryPage() {
|
||||
|
||||
return (
|
||||
<VStack gap={3}>
|
||||
{/* Above the header, because it is about the errand rather than the page:
|
||||
it is the only thing on screen that knows setup is unfinished. */}
|
||||
{fromSetup ? (
|
||||
<SetupReturnBar step={fromSetup} productCount={(setupProducts.data ?? []).length} />
|
||||
) : null}
|
||||
|
||||
<PageHeader
|
||||
title="Inventory"
|
||||
count={selected === null ? `${branches.length} branches` : current?.locationname}
|
||||
@@ -106,26 +145,26 @@ export function InventoryPage() {
|
||||
label="Products"
|
||||
icon={<PackageSearch size={14} />}
|
||||
isActive={tab === 'products'}
|
||||
onClick={() => setTab('products')}
|
||||
onClick={() => chooseTab('products')}
|
||||
/>
|
||||
<TabButton
|
||||
label="Catalogue"
|
||||
icon={<DownloadCloud size={14} />}
|
||||
isActive={tab === 'catalogue'}
|
||||
onClick={() => setTab('catalogue')}
|
||||
onClick={() => chooseTab('catalogue')}
|
||||
/>
|
||||
<TabButton
|
||||
label="Stock requests"
|
||||
icon={<ClipboardList size={14} />}
|
||||
isActive={tab === 'requests'}
|
||||
onClick={() => setTab('requests')}
|
||||
onClick={() => chooseTab('requests')}
|
||||
badge={pending.length || undefined}
|
||||
/>
|
||||
<TabButton
|
||||
label="Stock"
|
||||
icon={<Layers size={14} />}
|
||||
isActive={tab === 'stock'}
|
||||
onClick={() => setTab('stock')}
|
||||
onClick={() => chooseTab('stock')}
|
||||
/>
|
||||
</HStack>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user