Company Search
Company Search Page
In this section, we will build the Company Search page, enabling users to view, filter, and explore registered companies. This page will feature:
- A dynamic table displaying key company details
- Search filters
- Conditional styling based on company status
- Navigation links to detailed company pages
Step 1: Update the company-search.jsx File
Open the src/pages/company/company-search.jsx file and replace its contents with the following code:
import {SearchPage, StatusBubble, useLibrary} from 'so-kit-ui';
import config from '../../app-config.jsx';
import {basic_roles} from '../../library.jsx';
import {useEffect} from 'react';
import {Link} from 'react-router';
Define Column Rendering Logic
We define the columns array to control what gets displayed in each table column and how it should be rendered:
export const getColorForState = (state) => {
switch (state) {
case 'SUBMITTED':
return 'info';
case 'APPROVED':
return 'success';
case 'REJECTED':
return 'error';
}
};
const columns = [
{
accessor: 'data.companyName',
header: 'Company Name',
sortable: true,
width: '150px',
renderer: ({value, row}) => (
<Link to={`/companies/${row.id}/view`} className='font-semibold'>
{row?.data?.['companyName']}
</Link>
),
},
{
accessor: 'data.establishedDate',
header: 'Established Date',
sortable: true,
asDate: true,
width: '150px',
},
{
accessor: 'data.legalForm',
header: 'Legal Form',
sortable: true,
width: '150px',
},
{
accessor: 'data.employees',
header: 'Number of Employees',
sortable: true,
width: '150px',
},
{
accessor: 'data.vatNumber',
header: 'VAT Number',
sortable: true,
width: '150px',
},
{
accessor: 'metadata.current.state',
header: 'Status',
sortable: true,
width: '150px',
renderer: ({value}) => (
<div className='max-w-[100px]'>
<StatusBubble
outlined={false}
value={value}
color={getColorForState(value)}
/>
</div>
),
},
];
Add Filtering Capabilities
To allow users to filter results, define the filters array:
const filters = [
{
accessor: 'metadata.current.state',
label: 'Status',
type: 'select',
options: [
{value: 'APPROVED', label: 'Approved'},
{value: 'REJECTED', label: 'Rejected'},
{value: 'SUBMITTED', label: 'Submitted'},
],
inputProps: {
displayLabel: true,
},
},
{
accessor: 'data.establishedDate',
label: 'Established Date',
type: 'date',
},
];
💡 The available filters depend on what the backend supports. Confirm with the backend team before adding new filters.
Create the Page Component
The SearchPage component from SOKit UI handles the full rendering of the table and filters. Wrap it with the app's
layout and hooks like this:
export const CompanySearch = () => {
const {setBreadcrumbs} = useLibrary();
useEffect(() => {
setBreadcrumbs([{name: 'bc.company'}, {name: 'bc.search'}]);
}, []);
return (
<div className='me-auto w-full xl:max-w-[1280px] 2xl:max-w-[1536px] h-[calc(100vh-88px)]'>
<SearchPage
scope='company'
apiBase={config?.company?.apiBase}
apiUri={config?.company?.apiUri}
columns={columns}
filters={filters}
size={50}
roles={basic_roles}
tableProps={{
stackable: false,
}}
/>
</div>
);
};
As you can see there is a useEffect that sets the breadcrumbs for the page. This is important for navigation and user experience.
API Integration & Configuration
The values for apiBase and apiUri are pulled from the centralized app-config.jsx, keeping the configuration
environment-specific and clean.
⚠First-Time Run Note
Run the app using:
pnpm mock:dev
At this point, the table may show an error:

This is expected — mock data hasn't been set up yet, and the mock server isn’t running. You’ll add the mock data in upcoming steps.
Tips & Customization
- Add Columns: Insert new objects into the
columnsarray and configureaccessorandheader. - Add Filters: Similarly, add entries to the
filtersarray for filtering options. Always validate availability with the backend.
Navigating to Company View
Notice how the company name is wrapped in a Link component:
<Link to={`/companies/${row.id}/view`} className='font-semibold'>
{row?.data?.['companyName']}
</Link>
This links each row to a company detail page, which you’ll build in the next steps.