update page.tsx visual=true filter,
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
'use client';
|
||||
|
||||
// RULES:
|
||||
// contains list page for lesson_categories (LessonsCategories)
|
||||
// contain definition to collection only
|
||||
//
|
||||
import * as React from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { COL_LESSON_CATEGORIES } from '@/constants';
|
||||
@@ -14,6 +18,7 @@ import type { ListResult, RecordModel } from 'pocketbase';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { paths } from '@/paths';
|
||||
import isDevelopment from '@/lib/check-is-development';
|
||||
import { logger } from '@/lib/default-logger';
|
||||
import { pb } from '@/lib/pb';
|
||||
import { toast } from '@/components/core/toaster';
|
||||
@@ -39,55 +44,139 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
|
||||
const [isLoadingAddPage, setIsLoadingAddPage] = React.useState<boolean>(false);
|
||||
const [showLoading, setShowLoading] = React.useState<boolean>(true);
|
||||
const [showError, setShowError] = React.useState<boolean>(false);
|
||||
const [showError, setShowError] = React.useState({ show: false, detail: '' });
|
||||
//
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState<number>(5);
|
||||
//
|
||||
const [f, setF] = React.useState<LessonCategory[]>([]);
|
||||
const [currentPage, setCurrentPage] = React.useState<number>(1);
|
||||
//
|
||||
const [recordCount, setRecordCount] = React.useState<number>(0);
|
||||
|
||||
const sortedLessonCategories = applySort(lessonCategoriesData, sortDir);
|
||||
const filteredLessonCategories = applyFilters(sortedLessonCategories, { email, phone, status: status });
|
||||
const [listOption, setListOption] = React.useState({});
|
||||
const [listSort, setListSort] = React.useState({});
|
||||
|
||||
//
|
||||
const reloadRows = () => {
|
||||
const sortedLessonCategories = applySort(lessonCategoriesData, sortDir);
|
||||
const filteredLessonCategories = applyFilters(sortedLessonCategories, { email, phone, status });
|
||||
|
||||
//
|
||||
const reloadRows = async (): Promise<void> => {
|
||||
setShowLoading(true);
|
||||
|
||||
pb.collection(COL_LESSON_CATEGORIES)
|
||||
.getList(currentPage, rowsPerPage, {})
|
||||
.then((lessonCategories: ListResult<RecordModel>) => {
|
||||
// console.log(lessonTypes);
|
||||
const { items, page, perPage, totalItems, totalPages } = lessonCategories;
|
||||
const tempLessonCategories: LessonCategory[] = items.map((item) => {
|
||||
return { ...defaultLessonCategory, ...item };
|
||||
});
|
||||
|
||||
setLessonCategoriesData(tempLessonCategories);
|
||||
setRecordCount(totalItems);
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(err);
|
||||
toast(t('dashboard.lessonTypes.list.error'));
|
||||
setShowError(true);
|
||||
})
|
||||
.finally(() => {
|
||||
setShowLoading(false);
|
||||
try {
|
||||
const models: ListResult<RecordModel> = await pb
|
||||
.collection(COL_LESSON_CATEGORIES)
|
||||
.getList(currentPage + 1, rowsPerPage, listOption);
|
||||
const { items, totalItems } = models;
|
||||
const tempLessonTypes: LessonCategory[] = items.map((lt) => {
|
||||
return { ...defaultLessonCategory, ...lt };
|
||||
});
|
||||
|
||||
setLessonCategoriesData(tempLessonTypes);
|
||||
setRecordCount(totalItems);
|
||||
setF(tempLessonTypes);
|
||||
// console.log({ currentPage, f });
|
||||
} catch (error) {
|
||||
//
|
||||
logger.error(error);
|
||||
setShowError({
|
||||
//
|
||||
show: true,
|
||||
detail: JSON.stringify(error, null, 2),
|
||||
});
|
||||
} finally {
|
||||
setShowLoading(false);
|
||||
}
|
||||
|
||||
// pb.collection(COL_LESSON_CATEGORIES)
|
||||
// .getList(currentPage, rowsPerPage, listOption)
|
||||
// .then((lessonCategories: ListResult<RecordModel>) => {
|
||||
// // console.log(lessonTypes);
|
||||
// const { items, page, perPage, totalItems, totalPages } = lessonCategories;
|
||||
// const tempLessonCategories: LessonCategory[] = items.map((item) => {
|
||||
// return { ...defaultLessonCategory, ...item };
|
||||
// });
|
||||
|
||||
// setLessonCategoriesData(tempLessonCategories);
|
||||
// setRecordCount(totalItems);
|
||||
// setF(tempLessonCategories);
|
||||
// // console.log({ currentPage, f });
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// logger.error(error);
|
||||
// setShowError({
|
||||
// //
|
||||
// show: true,
|
||||
// detail: JSON.stringify(error, null, 2),
|
||||
// });
|
||||
// })
|
||||
// .finally(() => {
|
||||
// setShowLoading(false);
|
||||
// });
|
||||
};
|
||||
|
||||
const [lastListOption, setLastListOption] = React.useState({});
|
||||
const isFirstRun = React.useRef(false);
|
||||
React.useEffect(() => {
|
||||
reloadRows();
|
||||
}, []);
|
||||
if (!isFirstRun.current) {
|
||||
isFirstRun.current = true;
|
||||
} else {
|
||||
if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) {
|
||||
// reset page number as tab changes
|
||||
setLastListOption(listOption);
|
||||
setCurrentPage(0);
|
||||
void reloadRows();
|
||||
} else {
|
||||
void reloadRows();
|
||||
}
|
||||
}
|
||||
}, [currentPage, rowsPerPage, listOption]);
|
||||
|
||||
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}%"`);
|
||||
}
|
||||
|
||||
let preFinalListOption = {};
|
||||
if (tempFilter.length > 0) {
|
||||
preFinalListOption = { filter: tempFilter.join(' && ') };
|
||||
}
|
||||
if (tempSortDir.length > 0) {
|
||||
preFinalListOption = { ...preFinalListOption, sort: tempSortDir };
|
||||
}
|
||||
setListOption(preFinalListOption);
|
||||
// setListOption({
|
||||
// filter: tempFilter.join(' && '),
|
||||
// sort: tempSortDir,
|
||||
// //
|
||||
// });
|
||||
}, [visible, sortDir, name, type]);
|
||||
|
||||
// return <>helloworld</>;
|
||||
|
||||
if (showLoading) return <FormLoading />;
|
||||
|
||||
if (showError)
|
||||
if (showError.show)
|
||||
return (
|
||||
<ErrorDisplay
|
||||
message={t('error.unable-to-process-request', { ns: 'common' })}
|
||||
message={t('error.unable-to-process-request')}
|
||||
code="500"
|
||||
details={t('error.detailed-error-information', { ns: 'common' })}
|
||||
details={showError.detail}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -103,7 +192,11 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
}}
|
||||
>
|
||||
<Stack spacing={4}>
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={3} sx={{ alignItems: 'flex-start' }}>
|
||||
<Stack
|
||||
direction={{ xs: 'column', sm: 'row' }}
|
||||
spacing={3}
|
||||
sx={{ alignItems: 'flex-start' }}
|
||||
>
|
||||
<Box sx={{ flex: '1 1 auto' }}>
|
||||
<Typography variant="h4">{t('list.title')}</Typography>
|
||||
</Box>
|
||||
@@ -130,13 +223,25 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
/>
|
||||
<Divider />
|
||||
<Box sx={{ overflowX: 'auto' }}>
|
||||
<LessonCategoriesTable reloadRows={reloadRows} rows={filteredLessonCategories} />
|
||||
<LessonCategoriesTable
|
||||
reloadRows={reloadRows}
|
||||
rows={f}
|
||||
/>
|
||||
</Box>
|
||||
<Divider />
|
||||
<LessonCategoriesPagination count={filteredLessonCategories.length + 100} page={0} />
|
||||
<LessonCategoriesPagination
|
||||
count={recordCount}
|
||||
page={currentPage}
|
||||
rowsPerPage={rowsPerPage}
|
||||
setPage={setCurrentPage}
|
||||
setRowsPerPage={setRowsPerPage}
|
||||
/>
|
||||
</Card>
|
||||
</LessonCategoriesSelectionProvider>
|
||||
</Stack>
|
||||
<Box sx={{ display: isDevelopment ? 'block' : 'none' }}>
|
||||
<pre>{JSON.stringify(f, null, 2)}</pre>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -153,19 +258,19 @@ function applySort(row: LessonCategory[], sortDir: 'asc' | 'desc' | undefined):
|
||||
});
|
||||
}
|
||||
|
||||
function applyFilters(row: LessonCategory[], { email, phone, status }: Filters): LessonCategory[] {
|
||||
function applyFilters(row: LessonCategory[], { email, phone, status, name, visible }: Filters): LessonCategory[] {
|
||||
return row.filter((item) => {
|
||||
// if (email) {
|
||||
// if (!item.email?.toLowerCase().includes(email.toLowerCase())) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
if (email) {
|
||||
if (!item.email?.toLowerCase().includes(email.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if (phone) {
|
||||
// if (!item.phone?.toLowerCase().includes(phone.toLowerCase())) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
if (phone) {
|
||||
if (!item.phone?.toLowerCase().includes(phone.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (status) {
|
||||
if (item.status !== status) {
|
||||
@@ -173,6 +278,18 @@ function applyFilters(row: LessonCategory[], { email, phone, status }: Filters):
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
if (!item.name?.toLowerCase().includes(name.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
if (!item.visible?.toLowerCase().includes(visible.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -186,6 +303,5 @@ interface PageProps {
|
||||
name?: string;
|
||||
visible?: string;
|
||||
type?: string;
|
||||
//
|
||||
};
|
||||
}
|
||||
|
@@ -6,9 +6,9 @@ import { useParams, useRouter } from 'next/navigation';
|
||||
import SampleAddressCard from '@/app/dashboard/Sample/AddressCard';
|
||||
import BasicDetailCard from '@/app/dashboard/Sample/BasicDetailCard';
|
||||
import { SampleNotifications } from '@/app/dashboard/Sample/Notifications';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/SamplePaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SampleSecurityCard';
|
||||
import SampleTitleCard from '@/app/dashboard/Sample/SampleTitleCard';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/PaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SecurityCard';
|
||||
import SampleTitleCard from '@/app/dashboard/Sample/TitleCard';
|
||||
import Box from '@mui/material/Box';
|
||||
import Link from '@mui/material/Link';
|
||||
import Stack from '@mui/material/Stack';
|
||||
|
@@ -5,8 +5,8 @@ import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import SampleAddressCard from '@/app/dashboard/Sample/AddressCard';
|
||||
import { SampleNotifications } from '@/app/dashboard/Sample/Notifications';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/SamplePaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SampleSecurityCard';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/PaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SecurityCard';
|
||||
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
|
||||
import Box from '@mui/material/Box';
|
||||
import Link from '@mui/material/Link';
|
||||
|
@@ -44,8 +44,10 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
const [showError, setShowError] = React.useState({ show: false, detail: '' });
|
||||
//
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState<number>(5);
|
||||
//
|
||||
const [f, setF] = React.useState<LpCategory[]>([]);
|
||||
const [currentPage, setCurrentPage] = React.useState<number>(1);
|
||||
const [currentPage, setCurrentPage] = React.useState<number>(0);
|
||||
//
|
||||
const [recordCount, setRecordCount] = React.useState<number>(0);
|
||||
const [listOption, setListOption] = React.useState({});
|
||||
const [listSort, setListSort] = React.useState({});
|
||||
@@ -141,7 +143,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
return (
|
||||
<ErrorDisplay
|
||||
message={t('error.unable-to-process-request')}
|
||||
code="500"
|
||||
code={-1}
|
||||
details={showError.detail}
|
||||
/>
|
||||
);
|
||||
|
@@ -5,8 +5,8 @@ import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import SampleAddressCard from '@/app/dashboard/Sample/AddressCard';
|
||||
import { SampleNotifications } from '@/app/dashboard/Sample/Notifications';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/SamplePaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SampleSecurityCard';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/PaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SecurityCard';
|
||||
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
|
||||
import { Grid } from '@mui/material';
|
||||
import Box from '@mui/material/Box';
|
||||
|
@@ -44,8 +44,10 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
const [showError, setShowError] = React.useState({ show: false, detail: '' });
|
||||
//
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState<number>(5);
|
||||
//
|
||||
const [f, setF] = React.useState<LpQuestion[]>([]);
|
||||
const [currentPage, setCurrentPage] = React.useState<number>(0);
|
||||
//
|
||||
const [recordCount, setRecordCount] = React.useState<number>(0);
|
||||
const [listOption, setListOption] = React.useState({});
|
||||
const [listSort, setListSort] = React.useState({});
|
||||
|
1783
002_source/cms/src/app/dashboard/lp/repomix-output.xml
Normal file
1783
002_source/cms/src/app/dashboard/lp/repomix-output.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,8 @@ import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import SampleAddressCard from '@/app/dashboard/Sample/AddressCard';
|
||||
import { SampleNotifications } from '@/app/dashboard/Sample/Notifications';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/SamplePaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SampleSecurityCard';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/PaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SecurityCard';
|
||||
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
|
||||
import Box from '@mui/material/Box';
|
||||
import Link from '@mui/material/Link';
|
||||
|
@@ -13,7 +13,7 @@ import { ArrowLeft as ArrowLeftIcon } from '@phosphor-icons/react/dist/ssr/Arrow
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { paths } from '@/paths';
|
||||
import { MfCategoryCreateForm } from '@/components/dashboard/mf/categories/lp-category-create-form';
|
||||
import { MfCategoryCreateForm } from '@/components/dashboard/mf/categories/mf-category-create-form';
|
||||
|
||||
export default function Page(): React.JSX.Element {
|
||||
// RULES: follow the name of page directory
|
||||
|
@@ -33,8 +33,7 @@ import type { MfCategory } from '@/components/dashboard/mf/categories/type';
|
||||
import FormLoading from '@/components/loading';
|
||||
|
||||
export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
// TODO: modify from lp_categories to mf_categories
|
||||
const { t } = useTranslation(['lp_categories']);
|
||||
const { t } = useTranslation(['mf_categories']);
|
||||
const { email, phone, sortDir, status, name, visible, type } = searchParams;
|
||||
const router = useRouter();
|
||||
const [lessonCategoriesData, setLessonCategoriesData] = React.useState<MfCategory[]>([]);
|
||||
@@ -59,7 +58,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
try {
|
||||
const models: ListResult<RecordModel> = await pb
|
||||
.collection(COL_QUIZ_MF_CATEGORIES)
|
||||
.getList(currentPage + 1, rowsPerPage, {});
|
||||
.getList(currentPage + 1, rowsPerPage, listOption);
|
||||
const { items, totalItems } = models;
|
||||
const tempLessonTypes: MfCategory[] = items.map((lt) => {
|
||||
return { ...defaultMfCategory, ...lt };
|
||||
@@ -75,7 +74,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
setShowError({
|
||||
//
|
||||
show: true,
|
||||
detail: JSON.stringify(error),
|
||||
detail: JSON.stringify(error, null, 2),
|
||||
});
|
||||
} finally {
|
||||
setShowLoading(false);
|
||||
@@ -142,7 +141,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
return (
|
||||
<ErrorDisplay
|
||||
message={t('error.unable-to-process-request')}
|
||||
code="500"
|
||||
code={-1}
|
||||
details={showError.detail}
|
||||
/>
|
||||
);
|
||||
|
@@ -5,8 +5,8 @@ import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import SampleAddressCard from '@/app/dashboard/Sample/AddressCard';
|
||||
import { SampleNotifications } from '@/app/dashboard/Sample/Notifications';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/SamplePaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SampleSecurityCard';
|
||||
import SamplePaymentCard from '@/app/dashboard/Sample/PaymentCard';
|
||||
import SampleSecurityCard from '@/app/dashboard/Sample/SecurityCard';
|
||||
import { COL_QUIZ_MF_QUESTIONS } from '@/constants';
|
||||
import { Grid } from '@mui/material';
|
||||
import Box from '@mui/material/Box';
|
||||
|
@@ -33,7 +33,7 @@ import type { MfQuestion } from '@/components/dashboard/mf/questions/type';
|
||||
import FormLoading from '@/components/loading';
|
||||
|
||||
export default function Page({ searchParams }: PageProps): React.JSX.Element {
|
||||
const { t } = useTranslation(['lp_questions']);
|
||||
const { t } = useTranslation(['mf_question']);
|
||||
const { email, phone, sortDir, status, name, visible, type } = searchParams;
|
||||
const router = useRouter();
|
||||
const [lessonQuestionsData, setLessonCategoriesData] = React.useState<MfQuestion[]>([]);
|
||||
|
1663
002_source/cms/src/app/dashboard/mf/repomix-output.xml
Normal file
1663
002_source/cms/src/app/dashboard/mf/repomix-output.xml
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user