@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react'
import { formatINR , fromRupees } from '@sims/domain'
import {
Badge , Button , ConfirmDialog , DataTable , Dialog , EmptyState , ErrorState , Field , FormField ,
FormGrid , Notice , PageHeader , Skeleton , T oolbar, useToast ,
FormGrid , Notice , PageHeader , Skeleton , T abs, T oolbar, useToast ,
} from '@sims/ui'
import {
addPrice , assignClientModule , createModule , downloadModuleClientsCsv , getClients ,
@ -29,7 +29,9 @@ export function Modules() {
// Master → detail: selecting a module opens its own screen (derive from fresh data so the
// header + fields reflect edits immediately after a reload).
const [ selectedId , setSelectedId ] = useState < string | undefined > ( )
const [ detailTab , setDetailTab ] = useState < 'clients' | 'setup' > ( 'clients' )
const selected = module s.data?.find ( ( m ) = > m . id === selectedId )
const openModule = ( mid : string ) = > { setSelectedId ( mid ) ; setDetailTab ( 'clients' ) }
// How many clients sit on each module — one lightweight roster count per module,
// best-effort so a slow/failed one never blocks the table (cell shows '…' until then).
const [ clientCounts , setClientCounts ] = useState < Record < string , number > > ( { } )
@ -59,11 +61,24 @@ export function Modules() {
desc = { ` SAC ${ selected . sac } · ${ selected . allowedKinds . map ( ( k ) = > KIND_LABEL [ k ] ) . join ( ' · ' ) } · ${ selected . active ? 'active' : 'inactive' } ` }
actions = { < Button onClick = { ( ) = > setSelectedId ( undefined ) } > ← Back to all module s < / Button > }
/ >
< ModuleDetails key = { ` md- ${ selected . id } ` } module = { selected } isOwner = { isOwner } onSaved = { ( ) = > module s.reload ( ) } / >
< Tabs
tabs = { [
{ key : 'clients' , label : 'Clients' , count : clientCounts [ selected . id ] } ,
. . . ( isOwner ? [ { key : 'setup' , label : 'Setup' } ] : [ ] ) ,
] }
active = { detailTab }
onChange = { ( k ) = > setDetailTab ( k as 'clients' | 'setup' ) }
/ >
{ detailTab === 'clients' ? (
< ModuleClients key = { ` mc- ${ selected . id } ` } module = { selected } / >
) : (
< >
< ModuleDetails key = { ` md- ${ selected . id } ` } module = { selected } isOwner = { isOwner } onSaved = { ( ) = > module s.reload ( ) } / >
< FieldSpecEditor key = { ` fs- ${ selected . id } ` } module = { selected } isOwner = { isOwner } onSaved = { ( ) = > module s.reload ( ) } / >
< QuoteContent key = { selected . id } module = { selected } isOwner = { isOwner } onSaved = { ( ) = > module s.reload ( ) } / >
< PriceBook module = { selected } isOwner = { isOwner } / >
< / >
) }
< / div >
)
}
@ -88,14 +103,14 @@ export function Modules() {
{ key : 'multi' , label : 'Multi-sub' } , { key : 'active' , label : 'Active' } ,
{ key : 'act' , label : '' } ,
] }
onRowClick = { ( _row , i ) = > setSelectedId ( module s.data ! [ i ] ! . id ) }
onRowClick = { ( _row , i ) = > openModule ( module s.data ! [ i ] ! . id ) }
rows = { module s.data.map ( ( m ) = > ( {
code : m.code , name : m.name , sac : m.sac ,
clients : clientCounts [ m . id ] !== undefined ? clientCounts [ m . id ] : '…' ,
kinds : m.allowedKinds.map ( ( k ) = > KIND_LABEL [ k ] ) . join ( ' · ' ) ,
multi : m.multiSubscription ? < Badge tone = "accent" > yes < / Badge > : '—' ,
active : m.active ? < Badge tone = "ok" > active < / Badge > : < Badge > inactive < / Badge > ,
act : < span onClick = { ( e ) = > e . stopPropagation ( ) } > < Button onClick = { ( ) = > setSelectedId ( m . id ) } > Open → < / Button > < / span > ,
act : < span onClick = { ( e ) = > e . stopPropagation ( ) } > < Button onClick = { ( ) = > openModule ( m . id ) } > Open → < / Button > < / span > ,
} ) ) }
/ >
) }
@ -182,10 +197,9 @@ function ModuleClients(props: { module: Module }) {
const pages = data !== undefined ? Math . max ( 1 , Math . ceil ( data . total / data . pageSize ) ) : 1
return (
< section >
< h2 > Clients on this module < / h2 >
< Toolbar >
< Button onClick= { ( ) = > setAssigning ( ( v ) = > ! v ) } >
{ assigning ? 'Close assign' : 'Assign client… '}
< Button tone= "primary" onClick= { ( ) = > setAssigning ( ( v ) = > ! v ) } >
{ assigning ? 'Close ' : '+ Add client to this module '}
< / Button >
{ managerial && (
< Button onClick = { ( ) = > setNotifying ( ( v ) = > ! v ) } >