Skip to content

Commit

Permalink
feat(congregations): use pagination when navigating public talks
Browse files Browse the repository at this point in the history
  • Loading branch information
rhahao committed Jul 1, 2023
1 parent 0e2554f commit 62b056d
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 71 deletions.
31 changes: 14 additions & 17 deletions src/features/publicTalks/PublicTalkContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import { publicTalksListState } from '../../states/congregation';
import { LANGUAGE_LIST } from '../../constant/langList';
import { apiUpdatePublicTalk } from '../../api/congregation';

const PublicTalkContainer = ({ isNew, talk_number }) => {
const PublicTalkContainer = ({ talk_number }) => {
const [publicTalks, setPublicTalks] = useRecoilState(publicTalksListState);

const nextTalkNumber = publicTalks.length + 1;
const publicTalk = publicTalks.find((record) => record.talk_number === talk_number);

const handleSave = async (language, value) => {
const currentTalk = isNew ? nextTalkNumber : talk_number;
const currentTalk = talk_number;
const modifDate = new Date().toISOString();
language = language.toUpperCase();

Expand Down Expand Up @@ -52,22 +51,20 @@ const PublicTalkContainer = ({ isNew, talk_number }) => {
borderRadius: '5px',
}}
>
{isNew ? nextTalkNumber : publicTalk.talk_number}
{publicTalk.talk_number}
</Typography>
<Box sx={{ flexGrow: 1 }}>
<PublicTalkEditor isNew={isNew} public_talk={publicTalk} handleSaveData={handleSave} language="E" />
{!isNew && (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '10px', marginTop: '10px' }}>
{LANGUAGE_LIST.filter((lang) => !lang.isSource).map((language) => (
<PublicTalkEditor
language={language.code}
key={language.code}
public_talk={publicTalk}
handleSaveData={handleSave}
/>
))}
</Box>
)}
<PublicTalkEditor public_talk={publicTalk} handleSaveData={handleSave} language="E" />
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '10px', marginTop: '10px' }}>
{LANGUAGE_LIST.filter((lang) => !lang.isSource).map((language) => (
<PublicTalkEditor
language={language.code}
key={language.code}
public_talk={publicTalk}
handleSaveData={handleSave}
/>
))}
</Box>
</Box>
</Box>
);
Expand Down
27 changes: 9 additions & 18 deletions src/features/publicTalks/PublicTalkEditor.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useEffect, useState } from 'react';
import AddCircleIcon from '@mui/icons-material/AddCircle';
import Box from '@mui/material/Box';
import CheckIcon from '@mui/icons-material/Check';
import ClearIcon from '@mui/icons-material/Clear';
Expand All @@ -8,8 +7,8 @@ import IconButton from '@mui/material/IconButton';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';

const PublicTalkEditor = ({ isNew, handleSaveData, public_talk, language }) => {
const [isEdit, setIsEdit] = useState(isNew);
const PublicTalkEditor = ({ handleSaveData, public_talk, language }) => {
const [isEdit, setIsEdit] = useState(false);
const [title, setTitle] = useState('');

const handleEdit = () => {
Expand All @@ -18,24 +17,17 @@ const PublicTalkEditor = ({ isNew, handleSaveData, public_talk, language }) => {

const handleCancel = () => {
setIsEdit(false);
if (isNew) setTitle('');
if (!isNew) setTitle(public_talk[language.toUpperCase()]?.title || '');
setTitle(public_talk[language.toUpperCase()]?.title || '');
};

const handleSave = () => {
handleSaveData(language, title);
setIsEdit(isNew ? true : false);
if (isNew) setTitle('');
setIsEdit(false);
};

useEffect(() => {
if (isNew) setTitle('');
if (!isNew) setTitle(public_talk[language.toUpperCase()]?.title || '');
}, [isNew, public_talk, language]);

useEffect(() => {
setIsEdit(isNew);
}, [isNew]);
setTitle(public_talk[language.toUpperCase()]?.title || '');
}, [public_talk, language]);

return (
<Box>
Expand Down Expand Up @@ -68,7 +60,7 @@ const PublicTalkEditor = ({ isNew, handleSaveData, public_talk, language }) => {
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
{!isNew && public_talk[language.toUpperCase()] && (
{public_talk[language.toUpperCase()] && (
<Typography
align="right"
sx={{ fontSize: '14px', marginTop: '8px', fontStyle: 'italic', marginRight: '10px' }}
Expand All @@ -83,15 +75,14 @@ const PublicTalkEditor = ({ isNew, handleSaveData, public_talk, language }) => {
<EditIcon />
</IconButton>
)}
{isEdit && !isNew && (
{isEdit && (
<IconButton aria-label="save" color="error" onClick={handleCancel}>
<ClearIcon />
</IconButton>
)}
{isEdit && (
<IconButton aria-label="save" color="success" onClick={handleSave}>
{isNew && <AddCircleIcon />}
{!isNew && <CheckIcon />}
<CheckIcon />
</IconButton>
)}
</Box>
Expand Down
20 changes: 20 additions & 0 deletions src/features/publicTalks/PublicTalkPagination.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import TablePagination from '@mui/material/TablePagination';

const PublicTalkPagination = ({ count, page, handleChangePage, noLabel }) => {
return (
<TablePagination
component="div"
count={count}
page={page}
labelDisplayedRows={({ from, to, count }) => (noLabel ? '' : `${from}${to} / ${count}`)}
rowsPerPageOptions={[]}
rowsPerPage={10}
onPageChange={handleChangePage}
showFirstButton={true}
showLastButton={true}
sx={{ '.MuiTablePagination-displayedRows': { fontWeight: 'bold', fontSize: '16px' } }}
/>
);
};

export default PublicTalkPagination;
1 change: 1 addition & 0 deletions src/features/publicTalks/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as PublicTalkContainer } from './PublicTalkContainer';
export { default as PublicTalkImport } from './PublicTalkImport';
export { default as PublicTalkPagination } from './PublicTalkPagination';
85 changes: 49 additions & 36 deletions src/pages/PublicTalks.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,62 @@
import { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
import { useQuery } from '@tanstack/react-query';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import ImportExportIcon from '@mui/icons-material/ImportExport';
import Typography from '@mui/material/Typography';
import { publicTalkImportOpenState, publicTalksListState } from '../states/congregation';
import { PublicTalkContainer, PublicTalkImport } from '../features/publicTalks';
import { useEffect } from 'react';
import { PublicTalkContainer, PublicTalkImport, PublicTalkPagination } from '../features/publicTalks';
import { apiFetchPublicTalks } from '../api/congregation';

const PublicTalks = () => {
const { isLoading, data } = useQuery({
queryKey: ['public_talks'],
queryFn: apiFetchPublicTalks,
staleTime: 60000,
});

const [publicTalks, setPublicTalks] = useRecoilState(publicTalksListState);
const [openImport, setOpenImport] = useRecoilState(publicTalkImportOpenState);

const handleClickOpen = () => {
setOpenImport(true);
};

useEffect(() => {
if (!isLoading) setPublicTalks(data);
}, [isLoading, data, setPublicTalks]);

return (
<Box>
<Typography variant='h6'>PUBLIC TALKS</Typography>
<Button variant='outlined' startIcon={<ImportExportIcon />} sx={{ marginTop: '20px' }} onClick={handleClickOpen}>
Import JSON
</Button>

{openImport && <PublicTalkImport />}

<Box sx={{ margin: '20px 0', maxWidth: '900px', display: 'flex', flexDirection: 'column', gap: '25px' }}>
{publicTalks.map((talk) => (
<PublicTalkContainer key={talk.talk_number} talk_number={talk.talk_number} />
))}
<PublicTalkContainer isNew={true} />
</Box>
</Box>
);
const { isLoading, data } = useQuery({
queryKey: ['public_talks'],
queryFn: apiFetchPublicTalks,
staleTime: 60000,
});

const [publicTalks, setPublicTalks] = useRecoilState(publicTalksListState);
const [openImport, setOpenImport] = useRecoilState(publicTalkImportOpenState);

const [page, setPage] = useState(0);

const handleChangePage = (event, newPage) => {
setPage(newPage);
};

const handleClickOpen = () => {
setOpenImport(true);
};

useEffect(() => {
if (!isLoading) setPublicTalks(data);
}, [isLoading, data, setPublicTalks]);

return (
<Box>
<Typography variant="h6">PUBLIC TALKS</Typography>
<Button variant="outlined" startIcon={<ImportExportIcon />} sx={{ marginTop: '20px' }} onClick={handleClickOpen}>
Import JSON
</Button>

{openImport && <PublicTalkImport />}

<Box sx={{ margin: '20px 0', maxWidth: '900px', display: 'flex', flexDirection: 'column', gap: '25px' }}>
{publicTalks.length > 0 && (
<PublicTalkPagination count={publicTalks.length} page={page} handleChangePage={handleChangePage} />
)}

{publicTalks.slice(page * 10, page * 10 + 10).map((talk) => (
<PublicTalkContainer currentPage={page} key={talk.talk_number} talk_number={talk.talk_number} />
))}

{publicTalks.length > 0 && (
<PublicTalkPagination count={publicTalks.length} page={page} handleChangePage={handleChangePage} />
)}
</Box>
</Box>
);
};

export default PublicTalks;

0 comments on commit 62b056d

Please sign in to comment.