Skip to content

Commit

Permalink
feat: add admin panel (#330)
Browse files Browse the repository at this point in the history
* gql: add query to get count of total articles

* gql: add query to list all articles

* feat: add admin panel navigator

* feat: add admin panel header

* feat: add admin panel marginal

* feat: add category card

* feat: show logged in user profile pic

* chore: import hooks

* chore: destructure data

* feat: add authors card

* chore: change id type from string to int

* wip: add add categories function

* feat: add browse page

* feat: add mutation to create article

* feat: add query to list all user

* feat: add snack bar aleart

* chore: remove console log

* feat: add new article page

* chore: remove content component

* chore: add link to monday morning wesite in footer

* feat: show default users

* feat(graphql): add update article props

* feat(graphql): get restricted artcile data

* feat(graphql): add mutation to update article categories

* feat(graphql): add mutation to update article users

* feat: select default category

* chore: remove unuse import

* feat: add index page

* chore: remove console log

* feat: activate edit button

* feat: add media previewer

* wip: init image kit

* feat: add drop down

* feat(graphql): add mutation to update article cover

* feat(graphql): add mutation to add media

* wip: get cover media data

* feat: add loading indicator

* feat: add edit component

* feat: add media page and screen

* chore: sample content page

* wip: redirect to admin page after login

* feat: check permission

* feat: add error handling

* feat: update article publish status

* graphql: update article restriction

* feat(graphql): add update article approval status

* fix: get approval status

* feat: update article restriction and approval status

* feat: tags component
120EE0692 authored Dec 20, 2022
1 parent 89b505b commit a52cc19
Showing 39 changed files with 2,883 additions and 12 deletions.
45 changes: 45 additions & 0 deletions client/src/components/admin_v2/AddNew/AuthorCards.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from 'react';
import {
Card,
FormControl,
Typography,
Autocomplete,
TextField,
} from '@mui/material';

export default function AuthorsCard({ title, users, setTeam, defaultUsers }) {
const _defaultUsers = defaultUsers?.map((user) => {
return { ...user, label: user.name, id: user.details };
});

return (
<>
<div>
<Typography>{title}</Typography>
<FormControl
component='paper'
sx={{ width: '100', minWidth: '100%', margin: '20px 0' }}
>
<Autocomplete
multiple
id='multiple-limit-tags'
options={users}
defaultValue={_defaultUsers}
isOptionEqualToValue={(option, value) => option.id === value.id}
renderOption={(props, users) => (
<li {...props} key={users.id}>
{users.fullName}
</li>
)}
onChange={(e, value) => {
setTeam(value);
}}
renderInput={(params) => (
<TextField required={true} {...params} label='Name' />
)}
/>
</FormControl>
</div>
</>
);
}
46 changes: 46 additions & 0 deletions client/src/components/admin_v2/AddNew/CategoryCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useState } from 'react';
import Checkbox from '@mui/material/Checkbox';
import { Typography } from '@mui/material';

export default function CategoryCard({ explorer, addCategories, category }) {
const [expand, setExpand] = useState(explorer.name ? false : true);
return (
<>
{explorer.name && (
<span>
<div
style={{
display: 'flex',
alignItems: 'center',
}}
>
<Checkbox
defaultChecked={category?.has(explorer.id)}
onClick={() => addCategories(explorer.id)}
/>
<Typography
onClick={() => setExpand((exp) => !exp)}
style={{
fontWeight: explorer.items.length > 0 ? 'bolder' : 'normal',
}}
>
{explorer.name}
</Typography>
</div>
</span>
)}
<div style={{ display: expand ? 'block' : 'none', paddingLeft: '20px' }}>
{explorer.items.map((item) => {
return (
<CategoryCard
category={category}
explorer={item}
key={item.id}
addCategories={addCategories}
/>
);
})}
</div>
</>
);
}
149 changes: 149 additions & 0 deletions client/src/components/admin_v2/Browse/ArticleStatusMenu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useState, useEffect } from 'react';
import { styled, alpha } from '@mui/material/styles';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import ArchiveIcon from '@mui/icons-material/Archive';
import FileCopyIcon from '@mui/icons-material/FileCopy';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';

const StyledMenu = styled((props) => (
<Menu
elevation={0}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
{...props}
/>
))(({ theme }) => ({
'& .MuiPaper-root': {
borderRadius: 6,
marginTop: theme.spacing(1),
minWidth: 140,
color:
theme.palette.mode === 'light'
? 'rgb(55, 65, 81)'
: theme.palette.grey[300],
boxShadow:
'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px',
'& .MuiMenu-list': {
padding: '4px 0',
},
'& .MuiMenuItem-root': {
'& .MuiSvgIcon-root': {
fontSize: 12,
color: theme.palette.text.secondary,
marginRight: theme.spacing(1.5),
},
'&:active': {
backgroundColor: alpha(
theme.palette.primary.main,
theme.palette.action.selectedOpacity,
),
},
},
},
}));

const articleStatusMenu = ({
publishStatus,
id,
title,
handleDialogOpen,
updatePublishStatusResponse,
}) => {
const [status, setStatus] = useState(publishStatus);
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};

useEffect(() => {
if (!updatePublishStatusResponse?.data) return;
if (
id === updatePublishStatusResponse?.data?.updateArticlePublishStatus?.id
)
setStatus(
updatePublishStatusResponse?.data?.updateArticlePublishStatus
?.publishStatus,
);
}, [updatePublishStatusResponse]);

return (
<div>
<Button
id='demo-customized-button'
aria-controls={open ? 'demo-customized-menu' : undefined}
aria-haspopup='true'
aria-expanded={open ? 'true' : undefined}
variant='contained'
disableElevation
onClick={handleClick}
endIcon={<KeyboardArrowDownIcon />}
sx={{ fontSize: '10px' }}
color={status === 'PUBLISHED' ? 'success' : 'error'}
>
{status}
</Button>
<StyledMenu
id='demo-customized-menu'
MenuListProps={{
'aria-labelledby': 'demo-customized-button',
}}
anchorEl={anchorEl}
open={open}
onClose={handleClose}
>
<MenuItem
onClick={() => {
handleDialogOpen((status = 'PUBLISHED'), id, title), handleClose();
}}
disableRipple
>
<FileCopyIcon />
Publish
</MenuItem>
<MenuItem
onClick={() => {
handleDialogOpen((status = 'UNPUBLISHED'), id, title),
handleClose();
}}
disableRipple
>
<FileCopyIcon />
Unpublish
</MenuItem>
<MenuItem
onClick={() => {
handleDialogOpen((status = 'ARCHIVED'), id, title), handleClose();
}}
disableRipple
>
<ArchiveIcon />
Archive
</MenuItem>
<MenuItem
onClick={() => {
handleDialogOpen((status = 'TRASHED'), id, title), handleClose();
}}
disableRipple
>
<RemoveCircleOutlineIcon />
Trash
</MenuItem>
</StyledMenu>
</div>
);
};

export default articleStatusMenu;
47 changes: 47 additions & 0 deletions client/src/components/admin_v2/Browse/DialogBox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';

export default function AlertDialog({
openDialog,
handleDialogClose,
updatePublishStatus,
selectedArticle: { status, id, title },
}) {
return (
<div>
<Dialog
open={openDialog}
onClose={handleDialogClose}
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>
Do you want to {status.toLowerCase().slice(0, -2)} this article?
</DialogTitle>
<DialogContent>
<DialogContentText id='alert-dialog-description'>
Title: {title}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button
onClick={() => {
updatePublishStatus({ id, publishStatus: status }),
handleDialogClose();
}}
>
Yes
</Button>
<Button onClick={handleDialogClose} autoFocus>
No
</Button>
</DialogActions>
</Dialog>
</div>
);
}
Loading

0 comments on commit a52cc19

Please sign in to comment.