Make '/teks' dymamic & add Drawer components

This commit is contained in:
2020-12-13 23:20:07 +01:00
parent bdff3dae6a
commit 5b9a11a730
8 changed files with 422 additions and 34 deletions
+8 -2
View File
@@ -1,4 +1,5 @@
import React, {useRef, useEffect, useState} from 'react'
import {useRef, useEffect, useState} from 'react'
import {useRouter} from 'next/router'
import PropTypes from 'prop-types'
import {
@@ -28,6 +29,7 @@ export default function MizikBadjMeni({miziks}) {
const classes = useStyles()
const [open, setOpen] = useState(false)
const anchorRef = useRef(null)
const router = useRouter()
const handleToggle = () => {
setOpen(previousOpen_ => !previousOpen_)
@@ -41,6 +43,10 @@ export default function MizikBadjMeni({miziks}) {
setOpen(false)
}
const handleClick = slug => {
router.push(`/teks/${slug}#${slug}`)
}
function handleListKeyDown(event) {
if (event.key === 'Tab') {
event.preventDefault()
@@ -85,7 +91,7 @@ export default function MizikBadjMeni({miziks}) {
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id='menu-list-grow' onKeyDown={handleListKeyDown}>
{miziks.map(m => <MenuItem key={m._id} onClick={handleClose}>{m.titre}</MenuItem>)}
{miziks.map(m => <MenuItem key={m._id} onClick={() => handleClick(m.slug)}>{m.titre}</MenuItem>)}
</MenuList>
</ClickAwayListener>
</Paper>
+43 -9
View File
@@ -1,10 +1,8 @@
import React from 'react'
import PropTypes from 'prop-types'
import {useRouter} from 'next/router'
import {makeStyles} from '@material-ui/core/styles'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemText from '@material-ui/core/ListItemText'
import {List, ListItem, ListItemText} from '@material-ui/core'
const useStyles = makeStyles(theme => ({
root: {
@@ -14,14 +12,39 @@ const useStyles = makeStyles(theme => ({
}
}))
export default function MizikLis({miziks}) {
export default function MizikLis({setMobileOpen, hasAwtis, miziks, selectedMizikSlug, setSelectedMizikSlug}) {
const classes = useStyles()
const router = useRouter()
const handleClick = slug => {
if (setSelectedMizikSlug) {
setSelectedMizikSlug(slug)
}
if (slug !== selectedMizikSlug) {
if (hasAwtis) {
router.push(`/teks/${slug}`)
} else {
router.push(`/teks/${slug}#${slug}`)
}
}
if (setMobileOpen) {
setMobileOpen(false)
}
}
return (
<List component='nav' className={classes.root} aria-label='mizik'>
{miziks.map(m => (
<ListItem key={m._id} button>
<ListItemText primary={m.titre} />
{miziks.map(({slug, titre, awtis}) => (
<ListItem
key={slug}
button
id={slug}
selected={selectedMizikSlug === slug}
onClick={() => handleClick(slug)}
>
<ListItemText primary={titre} secondary={hasAwtis ? awtis.map(a => a.alias).join() : null} />
</ListItem>
))}
</List>
@@ -29,5 +52,16 @@ export default function MizikLis({miziks}) {
}
MizikLis.propTypes = {
miziks: PropTypes.array.isRequired
setMobileOpen: PropTypes.func,
hasAwtis: PropTypes.bool,
miziks: PropTypes.array.isRequired,
selectedMizikSlug: PropTypes.string,
setSelectedMizikSlug: PropTypes.func
}
MizikLis.defaultProps = {
setMobileOpen: null,
hasAwtis: false,
selectedMizikSlug: null,
setSelectedMizikSlug: null
}
+17
View File
@@ -0,0 +1,17 @@
import {makeStyles} from '@material-ui/core'
const useStyles = makeStyles(() => ({
container: {
marginTop: '2em'
}
}))
export default function DenyeTeks() {
const classes = useStyles()
return (
<div className={classes.container}>
Dènyé Tèks
</div>
)
}
+88
View File
@@ -0,0 +1,88 @@
import {useState} from 'react'
import PropTypes from 'prop-types'
import {
Divider,
FormControl,
InputAdornment,
InputBase,
makeStyles
} from '@material-ui/core'
import SearchIcon from '@material-ui/icons/Search'
import MizikLis from '../awtis/mizik-lis'
const useStyles = makeStyles(theme => ({
toolbar: theme.mixins.toolbar,
list: {
marginBottom: '6em'
},
form: {
marginLeft: theme.spacing(1)
},
text: {
marginBottom: '0.5em'
}
}))
const getMizikFiltered = (miziks, filter) => {
if (miziks) {
return miziks.filter(({titre}) => titre.toLowerCase().includes(filter.toLowerCase()))
}
}
export default function DrawerBar({setMobileOpen, miziks, mizik}) {
const slug = mizik ? mizik[0].slug : null
const classes = useStyles()
const [search, setSearch] = useState('')
const [selectedMizikSlug, setSelectedMizikSlug] = useState(slug)
const mizikFiltered = getMizikFiltered(miziks, search)
const handleSearch = event => {
event.preventDefault()
const value = event.target.value
setSearch(value)
}
return (
<div className='search'>
<FormControl className={classes.form}>
<InputBase
className={classes.toolbar}
placeholder='Chèché an tèks'
startAdornment={
<InputAdornment position='start'>
<SearchIcon />
</InputAdornment>
}
value={search}
onChange={handleSearch}
/>
</FormControl>
<Divider />
<div className={classes.list}>
<MizikLis
hasAwtis
setMobileOpen={setMobileOpen}
miziks={mizikFiltered}
selectedMizikSlug={selectedMizikSlug}
setSelectedMizikSlug={setSelectedMizikSlug}
/>
</div>
</div>
)
}
DrawerBar.propTypes = {
setMobileOpen: PropTypes.func,
miziks: PropTypes.array.isRequired,
mizik: PropTypes.array
}
DrawerBar.defaultProps = {
setMobileOpen: null,
mizik: null
}
+200
View File
@@ -0,0 +1,200 @@
import {useState} from 'react'
import PropTypes from 'prop-types'
import Link from 'next/link'
import {
Grid,
Toolbar,
Typography,
AppBar,
CssBaseline,
Drawer,
Hidden,
IconButton
} from '@material-ui/core'
import KeyboardBackspaceIcon from '@material-ui/icons/KeyboardBackspace'
import MenuIcon from '@material-ui/icons/Menu'
import {makeStyles, useTheme} from '@material-ui/core/styles'
import DrawerBar from './drawer-bar'
import DenyeTeks from './denye-teks'
const drawerWidth = 240
const useStyles = makeStyles(theme => ({
root: {
display: 'flex'
},
drawer: {
marginTop: '10em',
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0
}
},
appBar: {
borderTop: '2px solid #303030',
marginTop: '4.71rem',
[theme.breakpoints.up('sm')]: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth
}
},
menuButton: {
marginRight: theme.spacing(2),
[theme.breakpoints.up('sm')]: {
display: 'none'
}
},
toolbar: theme.mixins.toolbar,
drawerPaper: {
borderTop: '2px solid #303030',
marginTop: '4.71rem',
width: drawerWidth
},
content: {
flexGrow: 1,
padding: theme.spacing(3)
},
list: {
marginBottom: '6em'
},
form: {
marginLeft: theme.spacing(1)
},
text: {
marginBottom: '0.5em'
},
button: {
marginRight: '0.5em'
},
gridText: {
border: '1px dashed grey',
borderRadius: '5px',
marginTop: '2em',
marginInline: '2px'
},
grid: {
marginTop: '1em'
}
}))
const formatJsonString = stringToFormat => {
return stringToFormat.split('\n').map((string, index) => <div key={index}>{`${string}`}<br /></div>) // eslint-disable-line react/no-array-index-key
}
export default function TeksDrawer({miziks, mizik}) {
const teks = mizik ? mizik[0] : null
const classes = useStyles()
const theme = useTheme()
const [mobileOpen, setMobileOpen] = useState(false)
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen)
}
const container = typeof window === 'undefined' ? undefined : () => window.document.body
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position='fixed' className={classes.appBar}>
<Toolbar>
<IconButton
color='inherit'
aria-label='open drawer'
edge='start'
className={classes.menuButton}
onClick={handleDrawerToggle}
>
<MenuIcon />
</IconButton>
{teks ? (
<>
<Link href='/teks'>
<IconButton aria-label='return' className={classes.button} size='small'>
<KeyboardBackspaceIcon />
</IconButton>
</Link>
<Typography noWrap variant='h6'>
{teks.titre}
</Typography>
</>
) : (
<Typography noWrap variant='h6'>
Dènyé Tèks
</Typography>
)}
</Toolbar>
</AppBar>
<nav className={classes.drawer} aria-label='mailbox folders'>
<Hidden smUp implementation='css'>
<Drawer
container={container}
variant='temporary'
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
classes={{
paper: classes.drawerPaper
}}
ModalProps={{
keepMounted: true
}}
onClose={handleDrawerToggle}
>
<DrawerBar setMobileOpen={setMobileOpen} miziks={miziks} mizik={mizik} />
</Drawer>
</Hidden>
<Hidden xsDown implementation='css'>
<Drawer
open
classes={{
paper: classes.drawerPaper
}}
variant='permanent'
>
<DrawerBar miziks={miziks} mizik={mizik} />
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
{teks ? (
<Grid container className={classes.grid} spacing={3}>
<Grid item md className={classes.gridText}>
<Typography align='center' className={classes.text} variant='h4'>
Transcription
</Typography>
<Typography paragraph align='justify' component='span'>
{formatJsonString(teks.transcription)}
</Typography>
</Grid>
{teks.traductions && (
<Grid item md className={classes.gridText}>
<Typography align='center' className={classes.text} variant='h4'>
Traduction
</Typography>
<Typography paragraph align='justify' component='span'>
{formatJsonString(teks.traductions.francais)}
</Typography>
</Grid>
)}
</Grid>
) : (
<DenyeTeks />
)}
</main>
</div>
)
}
TeksDrawer.propTypes = {
miziks: PropTypes.array.isRequired,
mizik: PropTypes.array
}
TeksDrawer.defaultProps = {
mizik: null
}
-23
View File
@@ -1,23 +0,0 @@
import Navigasyon from '../components/navigasyon'
import {jwennTeks} from '../lib/oki-api'
export default function Teks() {
return (
<>
<Navigasyon selectedTab={2} />
<div>
Teks
</div>
</>
)
}
export async function getServerSideProps() {
const mizik = await jwennTeks()
return {
props: {
mizik
}
}
}
+37
View File
@@ -0,0 +1,37 @@
import PropTypes from 'prop-types'
import {jwennMizikEpiSlug, jwennTeks} from '../../lib/oki-api'
import Navigasyon from '../../components/navigasyon'
import TeksDrawer from '../../components/teks/teks-drawer'
export default function Mizik({miziks, mizik}) {
return (
<>
<Navigasyon selectedTab={2} />
<TeksDrawer miziks={miziks} mizik={mizik} />
</>
)
}
export async function getServerSideProps({query}) {
const {slug} = query
const miziks = await jwennTeks()
const mizik = await jwennMizikEpiSlug(slug)
if (mizik.length === 0) {
throw new Error('San répons')
}
return {
props: {
miziks,
mizik
}
}
}
Mizik.propTypes = {
miziks: PropTypes.array.isRequired,
mizik: PropTypes.array.isRequired
}
+29
View File
@@ -0,0 +1,29 @@
import PropTypes from 'prop-types'
import {jwennTeks} from '../../lib/oki-api'
import Navigasyon from '../../components/navigasyon'
import TeksDrawer from '../../components/teks/teks-drawer'
export default function Teks({miziks}) {
return (
<>
<Navigasyon selectedTab={2} />
<TeksDrawer miziks={miziks} />
</>
)
}
export async function getServerSideProps() {
const miziks = await jwennTeks()
return {
props: {
miziks
}
}
}
Teks.propTypes = {
miziks: PropTypes.array.isRequired
}