Skip to content

Commit

Permalink
Employee searchbar has been connected to the backend
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Kondratowicz committed Sep 20, 2024
1 parent f40a63b commit b23f7de
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 63 deletions.
20 changes: 2 additions & 18 deletions frontend/src/app/(app)/(root)/people/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
import { People } from '@app/components/pages/People';
import { createClient } from '@app/utils/supabase/server';
import { userStatus } from '@app/types/user';

async function getPeople(status?: keyof typeof userStatus) {
if (status) {
const supabase = createClient();
const { data, error } = await supabase.rpc('get_employees_by_status', { _status: status });

if (error) {
console.log('error', error);
} else {
return data;
}
}
}

export default async function PeoplePage({ searchParams }: { searchParams: { tab: keyof typeof userStatus } }) {
const data = await getPeople(searchParams.tab);
return <People data={data} />;
export default async function PeoplePage() {
return <People />;
}
30 changes: 23 additions & 7 deletions frontend/src/components/pages/People/People.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PeopleTableForm, peopleTableFormName } from './People.interface';
import { useQueryParams } from '@app/hooks';
import { Option } from '@app/types/common';
import { userStatus } from '@app/types/user';
import { useSearchParams } from 'next/navigation';

const tabs = [
{ name: userStatus.active, id: userStatus.active },
Expand All @@ -12,25 +13,39 @@ const tabs = [
];

export const usePeople = () => {
const { setParams } = useQueryParams();
const searchParams = useSearchParams();
const searchNameParam = searchParams.get('search');

const form = useForm<PeopleTableForm>({
mode: 'onChange',
defaultValues: {
[peopleTableFormName.band]: null,
[peopleTableFormName.search]: '',
[peopleTableFormName.search]: searchNameParam || null,
},
});

const [tab, setTab] = useState<Option>(tabs[0]);
const { setParams } = useQueryParams();
const values = form.watch();

const handleChangeTab = useCallback(() => {
setParams({ tab: tab.id });
}, [setParams, tab]);
const handleParamsChange = useCallback(() => {
const params = {
tab: tab.id,
search: values?.search || null,
};

setParams(params);
}, [setParams, tab, values?.search]);

useEffect(() => {
handleParamsChange();
}, [handleParamsChange, values?.search, tab, values?.search]);

useEffect(() => {
handleChangeTab();
}, [handleChangeTab, tab]);
if (values?.band?.id) {
setParams({ band: values?.band?.id });
}
}, [setParams, values.band]);

useEffect(() => {
if (values?.band?.id) {
Expand All @@ -48,5 +63,6 @@ export const usePeople = () => {
tabs,
form,
handleClearBand,
values,
};
};
6 changes: 1 addition & 5 deletions frontend/src/components/pages/People/People.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const peopleTableFormName = {

export interface PeopleTableForm {
[peopleTableFormName.band]: Option | null;
[peopleTableFormName.search]: string;
[peopleTableFormName.search]: string | null;
}

export interface Employee {
Expand Down Expand Up @@ -44,7 +44,3 @@ export interface PeopleDetails {
draft: number;
deactivated: number;
}

export interface PeopleProps {
data?: Employee[];
}
60 changes: 30 additions & 30 deletions frontend/src/components/pages/People/People.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import Link from 'next/link';
import { FormProvider } from '@app/components/common/FormProvider';
import { Input } from '@app/components/common/Input';
import { SearchIcon } from '@app/static/icons/SearchIcon';
import { bands } from './People.utils';
import { PeopleProps, PeopleTableForm, peopleTableFormName } from './People.interface';
import { bands, useGetPeopleList } from './People.utils';
import { PeopleTableForm, peopleTableFormName } from './People.interface';
import { routes } from '@app/constants';
import { Button } from '@app/components/common/Button';
import { Listbox } from '@app/components/common/Listbox';
import { PeopleTable } from './Modules/PeopleTable';
import { Tabs } from '@app/components/common/Tabs';
import { PlusIcon } from '@app/static/icons/PlusIcon';

import { FC } from 'react';
export const People = () => {
const { tab, setTab, tabs, form, handleClearBand, values } = usePeople();

export const People: FC<PeopleProps> = ({ data }) => {
const { tab, setTab, tabs, form, handleClearBand } = usePeople();
const { data: peopleData } = useGetPeopleList(tab.name, values?.search || '');

return (
<FormProvider<PeopleTableForm> form={form}>
<FormProvider<PeopleTableForm> onSubmit={() => null} form={form}>
<div className="flex flex-col gap-6">
<div className="flex items-center justify-between">
<Breadcrumbs breadcrumbs={[{ label: 'People', href: '/people', current: true }]} />
Expand All @@ -35,32 +35,32 @@ export const People: FC<PeopleProps> = ({ data }) => {
</Button>
</div>
<Tabs current={tab} onTabChange={setTab} tabs={tabs} />
{Array.isArray(data) && data.length > 0 ? (
<>
<div className="flex flex-col gap-2 rounded-2xl bg-white p-6">
<div className="w-2/5">
<div className="flex flex-wrap gap-3 lg:flex-nowrap">
<Input
name="search"
className="min-w-[304px]"
placeholder="Search"
leftIcon={<SearchIcon className="h-4 w-4" />}
/>
<Listbox
options={bands}
name={peopleTableFormName.band}
placeholder="Current band"
onClear={handleClearBand}
className="min-w-[160px]"
/>
</div>
<>
<div className="flex flex-col gap-2 rounded-2xl bg-white p-6">
<div className="w-2/5">
<div className="flex flex-wrap gap-3 lg:flex-nowrap">
<Input
name="search"
className="min-w-[304px]"
placeholder="Search"
leftIcon={<SearchIcon className="h-4 w-4" />}
/>
<Listbox
options={bands}
name={peopleTableFormName.band}
placeholder="Current band"
onClear={handleClearBand}
className="min-w-[160px]"
/>
</div>
<PeopleTable currentTab={tab} people={data} />
</div>
</>
) : (
<div>No data available</div>
)}
{Array.isArray(peopleData) && peopleData.length > 0 ? (
<PeopleTable currentTab={tab} people={peopleData} />
) : (
<div className="pt-8">No data available</div>
)}
</div>
</>
</div>
</FormProvider>
);
Expand Down
38 changes: 38 additions & 0 deletions frontend/src/components/pages/People/People.utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { createClient } from '@app/utils/supabase/client';
import { PostgrestError } from '@supabase/supabase-js';
import { useCallback, useEffect, useState } from 'react';
import { Employee } from './People.interface';

export const bands = [
{ name: 'Band 1', id: '1' },
{ name: 'Band 2', id: '2' },
Expand All @@ -16,3 +21,36 @@ export const employeeMenuOptions = [
label: 'Profile settings',
},
];

export const useGetPeopleList = (status: string, searchName: string) => {
const [data, setData] = useState<Employee[] | null>(null);
const [error, setError] = useState<PostgrestError | null>(null);
const [loading, setLoading] = useState(false);

const supabase = createClient();

const fetchPeopleList = useCallback(async () => {
if (status && searchName?.length !== 1) {
setLoading(true);
const { data, error } = await supabase.rpc('get_employees', {
_status: status,
_searchname: searchName,
});

if (error) {
console.log('error', error);
setError(error);
} else {
setData(data);
}

setLoading(false);
}
}, [status, searchName, supabase]);

useEffect(() => {
fetchPeopleList();
}, [fetchPeopleList]);

return { data, error, loading, refetch: fetchPeopleList };
};
8 changes: 5 additions & 3 deletions seed.sql
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ end;
$$ language plpgsql;

-- Function returning a table of filtered employees
CREATE OR REPLACE FUNCTION get_employees_by_status(_status profile_status DEFAULT NULL, current_user_id UUID DEFAULT NULL)
CREATE OR REPLACE FUNCTION get_employees(_status profile_status DEFAULT NULL, _searchName text DEFAULT NULL, current_user_id UUID DEFAULT NULL)
RETURNS TABLE (
id uuid,
email text,
Expand All @@ -80,7 +80,7 @@ security definer
AS $$
BEGIN
if current_user_id is not null then
raise exception 'get_employees_by_status() ERROR: current_user_id not implemented yet';
raise exception 'get_employees() ERROR: current_user_id not implemented yet';
end if;

RETURN QUERY
Expand All @@ -103,7 +103,9 @@ BEGIN
JOIN user_roles ur ON u.id = ur.user_id
FULL OUTER JOIN user_ladder ul ON u.id = ul.user_id
LEFT JOIN ladder l ON ul.ladder_slug = l.ladder_slug
WHERE _status IS NULL or _status = p.status;
WHERE (_status IS NULL OR _status = p.status)
AND (_searchName IS NULL OR p.first_name ILIKE '%' || _searchName || '%' OR p.last_name ILIKE '%' || _searchName || '%');


exception
when others then
Expand Down

0 comments on commit b23f7de

Please sign in to comment.