update table filter, it should be how working,gst
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
"lint:fix": "next lint --fix",
|
"lint:fix": "next lint --fix",
|
||||||
"lint:w": "pnpx nodemon --ext ts,tsx,json,mjs,js,jsx --delay 15 --exec \"pnpm run lint\"",
|
"lint:w": "pnpx nodemon --ext ts,tsx,json,mjs,js,jsx --delay 15 --exec \"pnpm run lint\"",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"typecheck:w": "pnpx nodemon --ext ts,tsx,json,mjs,js,jsx --delay 2 --exec \"pnpm run typecheck\" || exit 1",
|
"typecheck:w": "tsc --noEmit -w",
|
||||||
"format:write": "prettier --write \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
"format:write": "prettier --write \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
||||||
"format:check": "prettier --check \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
"format:check": "prettier --check \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
||||||
"format:fix": "prettier --write \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
"format:fix": "prettier --write \"**/*.{js,jsx,mjs,ts,tsx,mdx}\" --cache",
|
||||||
@@ -116,4 +116,4 @@
|
|||||||
"protobufjs"
|
"protobufjs"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,106 @@ const customers = [
|
|||||||
status: 'active',
|
status: 'active',
|
||||||
createdAt: dayjs().subtract(2, 'hour').subtract(2, 'day').toDate(),
|
createdAt: dayjs().subtract(2, 'hour').subtract(2, 'day').toDate(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-005',
|
||||||
|
name: 'Fran Perez',
|
||||||
|
avatar: '/assets/avatar-5.png',
|
||||||
|
email: 'fran.perez@domain.com',
|
||||||
|
phone: '(815) 704-0045',
|
||||||
|
quota: 50,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(1, 'hour').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-004',
|
||||||
|
name: 'Penjani Inyene',
|
||||||
|
avatar: '/assets/avatar-4.png',
|
||||||
|
email: 'penjani.inyene@domain.com',
|
||||||
|
phone: '(803) 937-8925',
|
||||||
|
quota: 100,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(3, 'hour').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-003',
|
||||||
|
name: 'Carson Darrin',
|
||||||
|
avatar: '/assets/avatar-3.png',
|
||||||
|
email: 'carson.darrin@domain.com',
|
||||||
|
phone: '(715) 278-5041',
|
||||||
|
quota: 10,
|
||||||
|
status: 'blocked',
|
||||||
|
createdAt: dayjs().subtract(1, 'hour').subtract(1, 'day').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-002',
|
||||||
|
name: 'Siegbert Gottfried',
|
||||||
|
avatar: '/assets/avatar-2.png',
|
||||||
|
email: 'siegbert.gottfried@domain.com',
|
||||||
|
phone: '(603) 766-0431',
|
||||||
|
quota: 0,
|
||||||
|
status: 'pending',
|
||||||
|
createdAt: dayjs().subtract(7, 'hour').subtract(1, 'day').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-001',
|
||||||
|
name: 'Miron Vitold',
|
||||||
|
avatar: '/assets/avatar-1.png',
|
||||||
|
email: 'miron.vitold@domain.com',
|
||||||
|
phone: '(425) 434-5535',
|
||||||
|
quota: 50,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(2, 'hour').subtract(2, 'day').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-005',
|
||||||
|
name: 'Fran Perez',
|
||||||
|
avatar: '/assets/avatar-5.png',
|
||||||
|
email: 'fran.perez@domain.com',
|
||||||
|
phone: '(815) 704-0045',
|
||||||
|
quota: 50,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(1, 'hour').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-004',
|
||||||
|
name: 'Penjani Inyene',
|
||||||
|
avatar: '/assets/avatar-4.png',
|
||||||
|
email: 'penjani.inyene@domain.com',
|
||||||
|
phone: '(803) 937-8925',
|
||||||
|
quota: 100,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(3, 'hour').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-003',
|
||||||
|
name: 'Carson Darrin',
|
||||||
|
avatar: '/assets/avatar-3.png',
|
||||||
|
email: 'carson.darrin@domain.com',
|
||||||
|
phone: '(715) 278-5041',
|
||||||
|
quota: 10,
|
||||||
|
status: 'blocked',
|
||||||
|
createdAt: dayjs().subtract(1, 'hour').subtract(1, 'day').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-002',
|
||||||
|
name: 'Siegbert Gottfried',
|
||||||
|
avatar: '/assets/avatar-2.png',
|
||||||
|
email: 'siegbert.gottfried@domain.com',
|
||||||
|
phone: '(603) 766-0431',
|
||||||
|
quota: 0,
|
||||||
|
status: 'pending',
|
||||||
|
createdAt: dayjs().subtract(7, 'hour').subtract(1, 'day').toDate(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'USR-001',
|
||||||
|
name: 'Miron Vitold',
|
||||||
|
avatar: '/assets/avatar-1.png',
|
||||||
|
email: 'miron.vitold@domain.com',
|
||||||
|
phone: '(425) 434-5535',
|
||||||
|
quota: 50,
|
||||||
|
status: 'active',
|
||||||
|
createdAt: dayjs().subtract(2, 'hour').subtract(2, 'day').toDate(),
|
||||||
|
},
|
||||||
] satisfies Customer[];
|
] satisfies Customer[];
|
||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
|
@@ -47,7 +47,7 @@ import { ShippingAddress } from '@/components/dashboard/lesson_type/shipping-add
|
|||||||
import FormLoading from '@/components/loading';
|
import FormLoading from '@/components/loading';
|
||||||
|
|
||||||
export default function Page(): React.JSX.Element {
|
export default function Page(): React.JSX.Element {
|
||||||
const { t } = useTranslation(['common']);
|
const { t } = useTranslation(['common', 'lesson_type']);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
//
|
//
|
||||||
const { type_id: typeId } = useParams<{ type_id: string }>();
|
const { type_id: typeId } = useParams<{ type_id: string }>();
|
||||||
|
@@ -19,7 +19,7 @@ import { pb } from '@/lib/pb';
|
|||||||
import { toast } from '@/components/core/toaster';
|
import { toast } from '@/components/core/toaster';
|
||||||
import ErrorDisplay from '@/components/dashboard/error';
|
import ErrorDisplay from '@/components/dashboard/error';
|
||||||
import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType';
|
import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType';
|
||||||
import { emptyLessonType, safeAssignment } from '@/components/dashboard/lesson_type/interfaces';
|
import { defaultLessonType, emptyLessonType, safeAssignment } from '@/components/dashboard/lesson_type/interfaces';
|
||||||
import { LessonTypesFilters } from '@/components/dashboard/lesson_type/lesson-types-filters';
|
import { LessonTypesFilters } from '@/components/dashboard/lesson_type/lesson-types-filters';
|
||||||
import type { Filters } from '@/components/dashboard/lesson_type/lesson-types-filters';
|
import type { Filters } from '@/components/dashboard/lesson_type/lesson-types-filters';
|
||||||
import { LessonTypesPagination } from '@/components/dashboard/lesson_type/lesson-types-pagination';
|
import { LessonTypesPagination } from '@/components/dashboard/lesson_type/lesson-types-pagination';
|
||||||
@@ -27,81 +27,77 @@ import { LessonTypesSelectionProvider } from '@/components/dashboard/lesson_type
|
|||||||
import { LessonTypesTable } from '@/components/dashboard/lesson_type/lesson-types-table';
|
import { LessonTypesTable } from '@/components/dashboard/lesson_type/lesson-types-table';
|
||||||
import FormLoading from '@/components/loading';
|
import FormLoading from '@/components/loading';
|
||||||
|
|
||||||
interface PageProps {
|
|
||||||
searchParams: {
|
|
||||||
email?: string;
|
|
||||||
phone?: string;
|
|
||||||
sortDir?: 'asc' | 'desc';
|
|
||||||
spStatus?: string;
|
|
||||||
spName?: string;
|
|
||||||
spVisible?: string;
|
|
||||||
spType?: string;
|
|
||||||
//
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { email, phone, sortDir, spStatus, spName, spVisible, spType } = searchParams;
|
const { email, phone, sortDir, status, name, visible, type } = searchParams;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [lessonTypesData, setLessonTypesData] = React.useState<LessonType[]>([]);
|
||||||
|
|
||||||
const [recordCount, setRecordCount] = React.useState<number>(0);
|
|
||||||
const [rowsPerPage, setRowsPerPage] = React.useState<number>(5);
|
|
||||||
const [currentPage, setCurrentPage] = React.useState<number>(1);
|
|
||||||
|
|
||||||
//
|
|
||||||
const [isLoadingAddPage, setIsLoadingAddPage] = React.useState<boolean>(false);
|
const [isLoadingAddPage, setIsLoadingAddPage] = React.useState<boolean>(false);
|
||||||
const [showLoading, setShowLoading] = React.useState<boolean>(true);
|
const [showLoading, setShowLoading] = React.useState<boolean>(true);
|
||||||
const [showError, setShowError] = React.useState<boolean>(false);
|
const [showError, setShowError] = React.useState<boolean>(false);
|
||||||
const [lessonTypesData, setLessonTypesData] = React.useState<LessonType[]>([]);
|
const [rowsPerPage, setRowsPerPage] = React.useState<number>(5);
|
||||||
// const [recordModel, setRecordModel] = React.useState<RecordModel[]>([]);
|
|
||||||
const sortedLessonTypes = applySort(lessonTypesData, sortDir);
|
|
||||||
const filteredLessonTypesOld = applyFilters(sortedLessonTypes, {
|
|
||||||
email,
|
|
||||||
phone,
|
|
||||||
spStatus,
|
|
||||||
spName,
|
|
||||||
spType,
|
|
||||||
spVisible,
|
|
||||||
//
|
|
||||||
});
|
|
||||||
|
|
||||||
const needToFill = 5 - filteredLessonTypesOld.length;
|
const [f, setF] = React.useState<LessonType[]>([]);
|
||||||
|
const [currentPage, setCurrentPage] = React.useState<number>(0);
|
||||||
|
const [recordCount, setRecordCount] = React.useState<number>(0);
|
||||||
|
|
||||||
const filteredLessonTypes: LessonType[] = filteredLessonTypesOld;
|
const [listOption, setListOption] = React.useState({});
|
||||||
for (let i = 0; i < needToFill; i++) {
|
const [listSort, setListSort] = React.useState({});
|
||||||
filteredLessonTypes.push(emptyLessonType);
|
|
||||||
}
|
|
||||||
|
|
||||||
const reloadRows = () => {
|
//
|
||||||
pb.collection(COL_LESSON_TYPES)
|
const reloadRows = async (): Promise<void> => {
|
||||||
.getList(currentPage, rowsPerPage, {})
|
try {
|
||||||
.then((lessonTypes: ListResult<RecordModel>) => {
|
const models: ListResult<RecordModel> = await pb
|
||||||
// console.log(lessonTypes);
|
.collection(COL_LESSON_TYPES)
|
||||||
const { items, page, perPage, totalItems, totalPages } = lessonTypes;
|
.getList(currentPage + 1, rowsPerPage, listOption);
|
||||||
const tempLessonTypes: LessonType[] = items.map((lt) => {
|
const { items, totalItems } = models;
|
||||||
return safeAssignment(lt);
|
const tempLessonTypes: LessonType[] = items.map((lt) => {
|
||||||
});
|
return { ...defaultLessonType, ...lt };
|
||||||
|
|
||||||
setLessonTypesData(tempLessonTypes);
|
|
||||||
setRecordCount(totalItems);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err);
|
|
||||||
toast(t('dashboard.lessonTypes.list.error'));
|
|
||||||
|
|
||||||
setShowError(true);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setShowLoading(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setLessonTypesData(tempLessonTypes);
|
||||||
|
setRecordCount(totalItems);
|
||||||
|
setF(tempLessonTypes);
|
||||||
|
} catch (error) {
|
||||||
|
//
|
||||||
|
} finally {
|
||||||
|
setShowLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
reloadRows();
|
void reloadRows();
|
||||||
}, []);
|
}, [currentPage, rowsPerPage, listOption]);
|
||||||
|
|
||||||
if (showLoading) return <FormLoading />;
|
React.useEffect(() => {
|
||||||
|
let tempFilter = [],
|
||||||
|
tempSortDir = '';
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
tempFilter.push(`visible = "${visible}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortDir) {
|
||||||
|
tempSortDir = `-created`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
tempFilter.push(`name ~ "%${name}%"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type) {
|
||||||
|
tempFilter.push(`type ~ "%${type}%"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setListOption({
|
||||||
|
filter: tempFilter.join(' && '),
|
||||||
|
sort: tempSortDir,
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}, [visible, sortDir, name, type]);
|
||||||
|
|
||||||
|
if (f.length === 0 || showLoading) return <FormLoading />;
|
||||||
|
|
||||||
if (showError)
|
if (showError)
|
||||||
return (
|
return (
|
||||||
@@ -137,24 +133,24 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
|||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
<LessonTypesSelectionProvider lessonTypes={filteredLessonTypes}>
|
<LessonTypesSelectionProvider lessonTypes={f}>
|
||||||
<Card>
|
<Card>
|
||||||
<LessonTypesFilters
|
<LessonTypesFilters
|
||||||
filters={{ email, phone, spStatus, spName, spVisible, spType }}
|
filters={{ email, phone, status, name, visible, type }}
|
||||||
fullData={lessonTypesData}
|
fullData={lessonTypesData}
|
||||||
sortDir={sortDir}
|
sortDir={sortDir}
|
||||||
/>
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Box sx={{ overflowX: 'auto' }}>
|
<Box sx={{ overflowX: 'auto' }}>
|
||||||
<LessonTypesTable reloadRows={reloadRows} rows={filteredLessonTypes} />
|
<LessonTypesTable reloadRows={reloadRows} rows={f} />
|
||||||
</Box>
|
</Box>
|
||||||
<Divider />
|
<Divider />
|
||||||
<LessonTypesPagination
|
<LessonTypesPagination
|
||||||
count={recordCount}
|
count={recordCount}
|
||||||
page={0}
|
page={currentPage}
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
|
setPage={setCurrentPage}
|
||||||
setRowsPerPage={setRowsPerPage}
|
setRowsPerPage={setRowsPerPage}
|
||||||
setCurrentPage={setCurrentPage}
|
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</LessonTypesSelectionProvider>
|
</LessonTypesSelectionProvider>
|
||||||
@@ -175,10 +171,7 @@ function applySort(row: LessonType[], sortDir: 'asc' | 'desc' | undefined): Less
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyFilters(
|
function applyFilters(row: LessonType[], { email, phone, status, name, visible }: Filters): LessonType[] {
|
||||||
row: LessonType[],
|
|
||||||
{ email, phone, spStatus: status, spName: name, spVisible }: Filters
|
|
||||||
): LessonType[] {
|
|
||||||
return row.filter((item) => {
|
return row.filter((item) => {
|
||||||
if (email) {
|
if (email) {
|
||||||
if (!item.email?.toLowerCase().includes(email.toLowerCase())) {
|
if (!item.email?.toLowerCase().includes(email.toLowerCase())) {
|
||||||
@@ -204,8 +197,8 @@ function applyFilters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spVisible) {
|
if (visible) {
|
||||||
if (!item.visible?.toLowerCase().includes(spVisible.toLowerCase())) {
|
if (!item.visible?.toLowerCase().includes(visible.toLowerCase())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,3 +206,16 @@ function applyFilters(
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PageProps {
|
||||||
|
searchParams: {
|
||||||
|
email?: string;
|
||||||
|
phone?: string;
|
||||||
|
sortDir?: 'asc' | 'desc';
|
||||||
|
status?: string;
|
||||||
|
name?: string;
|
||||||
|
visible?: string;
|
||||||
|
type?: string;
|
||||||
|
//
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@@ -25,6 +25,7 @@ export function CustomersPagination({ count, page }: CustomersPaginationProps):
|
|||||||
page={page}
|
page={page}
|
||||||
rowsPerPage={5}
|
rowsPerPage={5}
|
||||||
rowsPerPageOptions={[5, 10, 25]}
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
|
//
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { COL_LESSON_TYPES } from '@/constants';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import Chip from '@mui/material/Chip';
|
import Chip from '@mui/material/Chip';
|
||||||
import Divider from '@mui/material/Divider';
|
import Divider from '@mui/material/Divider';
|
||||||
@@ -16,6 +17,7 @@ import Typography from '@mui/material/Typography';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { paths } from '@/paths';
|
import { paths } from '@/paths';
|
||||||
|
import { pb } from '@/lib/pb';
|
||||||
import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button';
|
import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button';
|
||||||
import { Option } from '@/components/core/option';
|
import { Option } from '@/components/core/option';
|
||||||
|
|
||||||
@@ -25,10 +27,10 @@ import { useLessonTypesSelection } from './lesson-types-selection-context';
|
|||||||
export interface Filters {
|
export interface Filters {
|
||||||
email?: string;
|
email?: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
spStatus?: string;
|
status?: string;
|
||||||
spName?: string;
|
name?: string;
|
||||||
spVisible?: string;
|
visible?: string;
|
||||||
spType?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SortDir = 'asc' | 'desc';
|
export type SortDir = 'asc' | 'desc';
|
||||||
@@ -45,7 +47,11 @@ export function LessonTypesFilters({
|
|||||||
fullData,
|
fullData,
|
||||||
}: LessonTypesFiltersProps): React.JSX.Element {
|
}: LessonTypesFiltersProps): React.JSX.Element {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { email, phone, spStatus: status, spName, spVisible, spType } = filters;
|
const { email, phone, status, name, visible, type } = filters;
|
||||||
|
|
||||||
|
const [totalCount, setTotalCount] = React.useState<number>(0);
|
||||||
|
const [visibleCount, setVisibleCount] = React.useState<number>(0);
|
||||||
|
const [hiddenCount, setHiddenCount] = React.useState<number>(0);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -65,12 +71,12 @@ export function LessonTypesFilters({
|
|||||||
|
|
||||||
// The tabs should be generated using API data.
|
// The tabs should be generated using API data.
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ label: 'All', value: '', count: fullData.length },
|
{ label: t('All'), value: '', count: totalCount },
|
||||||
// { label: 'Active', value: 'active', count: 3 },
|
// { label: 'Active', value: 'active', count: 3 },
|
||||||
// { label: 'Pending', value: 'pending', count: 1 },
|
// { label: 'Pending', value: 'pending', count: 1 },
|
||||||
// { label: 'Blocked', value: 'blocked', count: 1 },
|
// { label: 'Blocked', value: 'blocked', count: 1 },
|
||||||
{ label: t('visible'), value: 'visible', count: getVisible() },
|
{ label: t('visible'), value: 'visible', count: visibleCount },
|
||||||
{ label: t('hidden'), value: 'hidden', count: getHidden() },
|
{ label: t('hidden'), value: 'hidden', count: hiddenCount },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const updateSearchParams = React.useCallback(
|
const updateSearchParams = React.useCallback(
|
||||||
@@ -81,8 +87,8 @@ export function LessonTypesFilters({
|
|||||||
searchParams.set('sortDir', newSortDir);
|
searchParams.set('sortDir', newSortDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFilters.spStatus) {
|
if (newFilters.status) {
|
||||||
searchParams.set('status', newFilters.spStatus);
|
searchParams.set('status', newFilters.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFilters.email) {
|
if (newFilters.email) {
|
||||||
@@ -93,16 +99,16 @@ export function LessonTypesFilters({
|
|||||||
searchParams.set('phone', newFilters.phone);
|
searchParams.set('phone', newFilters.phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFilters.spName) {
|
if (newFilters.name) {
|
||||||
searchParams.set('name', newFilters.spName);
|
searchParams.set('name', newFilters.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFilters.spType) {
|
if (newFilters.type) {
|
||||||
searchParams.set('type', newFilters.spType);
|
searchParams.set('type', newFilters.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFilters.spVisible) {
|
if (newFilters.visible) {
|
||||||
searchParams.set('visible', newFilters.spVisible);
|
searchParams.set('visible', newFilters.visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
router.push(`${paths.dashboard.lesson_types.list}?${searchParams.toString()}`);
|
router.push(`${paths.dashboard.lesson_types.list}?${searchParams.toString()}`);
|
||||||
@@ -116,28 +122,28 @@ export function LessonTypesFilters({
|
|||||||
|
|
||||||
const handleStatusChange = React.useCallback(
|
const handleStatusChange = React.useCallback(
|
||||||
(_: React.SyntheticEvent, value: string) => {
|
(_: React.SyntheticEvent, value: string) => {
|
||||||
updateSearchParams({ ...filters, spStatus: value }, sortDir);
|
updateSearchParams({ ...filters, status: value }, sortDir);
|
||||||
},
|
},
|
||||||
[updateSearchParams, filters, sortDir]
|
[updateSearchParams, filters, sortDir]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleVisibleChange = React.useCallback(
|
const handleVisibleChange = React.useCallback(
|
||||||
(_: React.SyntheticEvent, value: string) => {
|
(_: React.SyntheticEvent, value: string) => {
|
||||||
updateSearchParams({ ...filters, spVisible: value }, sortDir);
|
updateSearchParams({ ...filters, visible: value }, sortDir);
|
||||||
},
|
},
|
||||||
[updateSearchParams, filters, sortDir]
|
[updateSearchParams, filters, sortDir]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleNameChange = React.useCallback(
|
const handleNameChange = React.useCallback(
|
||||||
(value?: string) => {
|
(value?: string) => {
|
||||||
updateSearchParams({ ...filters, spName: value }, sortDir);
|
updateSearchParams({ ...filters, name: value }, sortDir);
|
||||||
},
|
},
|
||||||
[updateSearchParams, filters, sortDir]
|
[updateSearchParams, filters, sortDir]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTypeChange = React.useCallback(
|
const handleTypeChange = React.useCallback(
|
||||||
(value?: string) => {
|
(value?: string) => {
|
||||||
updateSearchParams({ ...filters, spType: value }, sortDir);
|
updateSearchParams({ ...filters, type: value }, sortDir);
|
||||||
},
|
},
|
||||||
[updateSearchParams, filters, sortDir]
|
[updateSearchParams, filters, sortDir]
|
||||||
);
|
);
|
||||||
@@ -163,11 +169,33 @@ export function LessonTypesFilters({
|
|||||||
[updateSearchParams, filters]
|
[updateSearchParams, filters]
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasFilters = status || email || phone || spVisible || spName || spType;
|
React.useEffect(() => {
|
||||||
|
const fetchCount = async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const { totalItems: tc } = await pb.collection(COL_LESSON_TYPES).getList(1, 9999);
|
||||||
|
setTotalCount(tc);
|
||||||
|
|
||||||
|
const { totalItems: vc } = await pb
|
||||||
|
.collection(COL_LESSON_TYPES)
|
||||||
|
.getList(1, 9999, { filter: 'visible = "visible"' });
|
||||||
|
setVisibleCount(vc);
|
||||||
|
|
||||||
|
const { totalItems: hc } = await pb
|
||||||
|
.collection(COL_LESSON_TYPES)
|
||||||
|
.getList(1, 9999, { filter: 'visible = "hidden"' });
|
||||||
|
setHiddenCount(hc);
|
||||||
|
} catch (error) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
||||||
|
void fetchCount();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const hasFilters = status || email || phone || visible || name || type;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Tabs onChange={handleVisibleChange} sx={{ px: 3 }} value={spVisible ?? ''} variant="scrollable">
|
<Tabs onChange={handleVisibleChange} sx={{ px: 3 }} value={visible ?? ''} variant="scrollable">
|
||||||
{tabs.map((tab) => (
|
{tabs.map((tab) => (
|
||||||
<Tab
|
<Tab
|
||||||
icon={<Chip label={tab.count} size="small" variant="soft" />}
|
icon={<Chip label={tab.count} size="small" variant="soft" />}
|
||||||
@@ -184,7 +212,7 @@ export function LessonTypesFilters({
|
|||||||
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flexWrap: 'wrap', px: 3, py: 2 }}>
|
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flexWrap: 'wrap', px: 3, py: 2 }}>
|
||||||
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flex: '1 1 auto', flexWrap: 'wrap' }}>
|
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flex: '1 1 auto', flexWrap: 'wrap' }}>
|
||||||
<FilterButton
|
<FilterButton
|
||||||
displayValue={spName}
|
displayValue={name}
|
||||||
label={t('Name')}
|
label={t('Name')}
|
||||||
onFilterApply={(value) => {
|
onFilterApply={(value) => {
|
||||||
handleNameChange(value as string);
|
handleNameChange(value as string);
|
||||||
@@ -193,11 +221,11 @@ export function LessonTypesFilters({
|
|||||||
handleNameChange();
|
handleNameChange();
|
||||||
}}
|
}}
|
||||||
popover={<NameFilterPopover />}
|
popover={<NameFilterPopover />}
|
||||||
value={spName}
|
value={name}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FilterButton
|
<FilterButton
|
||||||
displayValue={spType}
|
displayValue={type}
|
||||||
label={t('Type')}
|
label={t('Type')}
|
||||||
onFilterApply={(value) => {
|
onFilterApply={(value) => {
|
||||||
handleTypeChange(value as string);
|
handleTypeChange(value as string);
|
||||||
@@ -206,7 +234,7 @@ export function LessonTypesFilters({
|
|||||||
handleTypeChange();
|
handleTypeChange();
|
||||||
}}
|
}}
|
||||||
popover={<TypeFilterPopover />}
|
popover={<TypeFilterPopover />}
|
||||||
value={spType}
|
value={type}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
|
@@ -10,48 +10,39 @@ function noop(): void {
|
|||||||
interface LessonTypesPaginationProps {
|
interface LessonTypesPaginationProps {
|
||||||
count: number;
|
count: number;
|
||||||
page: number;
|
page: number;
|
||||||
|
setPage: (page: number) => void;
|
||||||
|
setRowsPerPage: (page: number) => void;
|
||||||
rowsPerPage: number;
|
rowsPerPage: number;
|
||||||
setRowsPerPage: React.Dispatch<React.SetStateAction<number>>;
|
|
||||||
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LessonTypesPagination({
|
export function LessonTypesPagination({
|
||||||
count,
|
count,
|
||||||
page,
|
page,
|
||||||
rowsPerPage,
|
setPage,
|
||||||
setRowsPerPage,
|
setRowsPerPage,
|
||||||
setCurrentPage,
|
rowsPerPage,
|
||||||
}: LessonTypesPaginationProps): React.JSX.Element {
|
}: LessonTypesPaginationProps): React.JSX.Element {
|
||||||
// You should implement the pagination using a similar logic as the filters.
|
// You should implement the pagination using a similar logic as the filters.
|
||||||
// Note that when page change, you should keep the filter search params.
|
// Note that when page change, you should keep the filter search params.
|
||||||
|
const handleChangePage = (event: unknown, newPage: number) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
function handleRowsPerPageChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void {
|
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
console.log(e.target.value);
|
setRowsPerPage(parseInt(event.target.value));
|
||||||
console.log(parseInt(e.target.value));
|
// console.log(parseInt(event.target.value));
|
||||||
setRowsPerPage(parseInt(e.target.value));
|
};
|
||||||
}
|
|
||||||
|
|
||||||
function handlePageChange(e: React.MouseEvent<HTMLButtonElement> | null): void {
|
|
||||||
// console.log(e.target.value);
|
|
||||||
// console.log(parseInt(e.target.value));
|
|
||||||
// setCurrentPage(parseInt(e.target.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TablePagination
|
<TablePagination
|
||||||
component="div"
|
component="div"
|
||||||
count={count}
|
count={count}
|
||||||
page={page}
|
page={page}
|
||||||
//
|
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
rowsPerPageOptions={[5, 10, 25]}
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
//
|
//
|
||||||
onPageChange={(e) => {
|
onPageChange={handleChangePage}
|
||||||
handlePageChange(e);
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
}}
|
|
||||||
onRowsPerPageChange={(e) => {
|
|
||||||
handleRowsPerPageChange(e);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -83,27 +83,27 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonT
|
|||||||
</Stack>
|
</Stack>
|
||||||
),
|
),
|
||||||
name: 'Lesson position',
|
name: 'Lesson position',
|
||||||
width: '150px',
|
width: '50px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formatter: (row): React.JSX.Element => {
|
formatter: (row): React.JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
const { t } = useTranslation();
|
// const { t } = useTranslation();
|
||||||
|
|
||||||
const mapping = {
|
const mapping = {
|
||||||
active: { label: 'Active', icon: <CheckCircleIcon color="var(--mui-palette-success-main)" weight="fill" /> },
|
active: { label: 'Active', icon: <CheckCircleIcon color="var(--mui-palette-success-main)" weight="fill" /> },
|
||||||
blocked: { label: 'Blocked', icon: <MinusIcon color="var(--mui-palette-error-main)" /> },
|
blocked: { label: 'Blocked', icon: <MinusIcon color="var(--mui-palette-error-main)" /> },
|
||||||
pending: { label: 'Pending', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
pending: { label: 'Pending', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
||||||
visible: {
|
visible: {
|
||||||
label: t('visible'),
|
label: 'visible',
|
||||||
icon: <ClockIcon color="var(--mui-palette-success-main)" weight="fill" />,
|
icon: <ClockIcon color="var(--mui-palette-success-main)" weight="fill" />,
|
||||||
},
|
},
|
||||||
hidden: {
|
hidden: {
|
||||||
label: t('hidden'),
|
label: 'hidden',
|
||||||
icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" />,
|
icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" />,
|
||||||
},
|
},
|
||||||
no_value: {
|
no_value: {
|
||||||
label: t('no_value'),
|
label: 'no_value',
|
||||||
icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" />,
|
icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" />,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
@@ -123,7 +123,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonT
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
name: 'visible',
|
name: 'visible',
|
||||||
width: '150px',
|
width: '100px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
formatter(row) {
|
formatter(row) {
|
||||||
|
Reference in New Issue
Block a user