From bce6c6c6a3fa70331719233f0ca23f8437df9992 Mon Sep 17 00:00:00 2001 From: Albin Henriksson <albhe428@student.liu.se> Date: Tue, 20 Apr 2021 17:24:11 +0000 Subject: [PATCH] Resolve "Add slide button" --- .../PresentationEditorPage.tsx | 106 ++++++++++++++---- .../components/CompetitionSettings.tsx | 2 +- .../src/pages/presentationEditor/styled.tsx | 10 +- 3 files changed, 97 insertions(+), 21 deletions(-) diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx index eca24885..7b6f2eba 100644 --- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx +++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx @@ -1,14 +1,15 @@ -import { Button, CircularProgress, Divider, Typography } from '@material-ui/core' +import { Button, CircularProgress, Divider, Menu, MenuItem, Typography } from '@material-ui/core' import AppBar from '@material-ui/core/AppBar' import CssBaseline from '@material-ui/core/CssBaseline' import Drawer from '@material-ui/core/Drawer' -import List from '@material-ui/core/List' import ListItemText from '@material-ui/core/ListItemText' import { createStyles, makeStyles, Theme } from '@material-ui/core/styles' +import AddOutlinedIcon from '@material-ui/icons/AddOutlined' import BuildOutlinedIcon from '@material-ui/icons/BuildOutlined' import CreateOutlinedIcon from '@material-ui/icons/CreateOutlined' import DnsOutlinedIcon from '@material-ui/icons/DnsOutlined' import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined' +import axios from 'axios' import React, { useEffect } from 'react' import { Link, useParams } from 'react-router-dom' import { getCities } from '../../actions/cities' @@ -16,6 +17,7 @@ import { getEditorCompetition, setEditorSlideId } from '../../actions/editor' import { getTypes } from '../../actions/typesAction' import { useAppDispatch, useAppSelector } from '../../hooks' import { RichSlide } from '../../interfaces/ApiRichModels' +import { RemoveMenuItem } from '../admin/styledComp' import { Content } from '../views/styled' import SettingsPanel from './components/SettingsPanel' import SlideEditor from './components/SlideEditor' @@ -23,14 +25,17 @@ import { CenteredSpinnerContainer, HomeIcon, PresentationEditorContainer, + SlideList, SlideListItem, ToolBarContainer, ViewButton, ViewButtonGroup, } from './styled' -function createSlide(name: string) { - return { name } +const initialState = { + mouseX: null, + mouseY: null, + slideOrder: null, } const leftDrawerWidth = 150 @@ -92,6 +97,45 @@ const PresentationEditorPage: React.FC = () => { dispatch(setEditorSlideId(id)) } + const createNewSlide = async () => { + await axios.post(`/competitions/${id}/slides`, { title: 'new slide' }) + dispatch(getEditorCompetition(id)) + } + + const [contextState, setContextState] = React.useState<{ + mouseX: null | number + mouseY: null | number + slideOrder: null | number + }>(initialState) + + const handleRightClick = (event: React.MouseEvent<HTMLDivElement>, slideOrder: number) => { + event.preventDefault() + setContextState({ + mouseX: event.clientX - 2, + mouseY: event.clientY - 4, + slideOrder: slideOrder, + }) + } + + const handleClose = () => { + setContextState(initialState) + } + + const handleRemoveSlide = async () => { + await axios.delete(`/competitions/${id}/slides/${contextState.slideOrder}`) + dispatch(getEditorCompetition(id)) + setContextState(initialState) + } + + const handleDuplicateSlide = async () => { + const response = await axios.post(`/competitions/${id}/slides`) + const newOrder = response.data.items[response.data.total_count - 1].order + const oldSlide = competition.slides.find((slide) => slide.order === contextState.slideOrder) + await axios.put(`/competitions/${id}/slides/${newOrder}`, { timer: oldSlide?.timer, title: oldSlide?.title }) + dispatch(getEditorCompetition(id)) + setContextState(initialState) + } + const renderSlideIcon = (slide: RichSlide) => { switch (slide.questions[0].type_id) { case 0: @@ -139,21 +183,31 @@ const PresentationEditorPage: React.FC = () => { > <div className={classes.toolbar} /> <Divider /> - <List> - {competition.slides && - competition.slides.map((slide) => ( - <SlideListItem - divider - button - key={slide.id} - selected={slide.id === activeSlideId} - onClick={() => setActiveSlideId(slide.id)} - > - {renderSlideIcon(slide)} - <ListItemText primary={slide.title} /> - </SlideListItem> - ))} - </List> + <SlideList> + <div> + {competition.slides && + competition.slides.map((slide) => ( + <SlideListItem + divider + button + key={slide.id} + selected={slide.id === activeSlideId} + onClick={() => setActiveSlideId(slide.id)} + onContextMenu={(event) => handleRightClick(event, slide.order)} + > + {renderSlideIcon(slide)} + <ListItemText primary={`Sida ${slide.order + 1}`} /> + </SlideListItem> + ))} + </div> + <div> + <Divider /> + <SlideListItem divider button onClick={() => createNewSlide()}> + <ListItemText primary="Ny sida" /> + <AddOutlinedIcon /> + </SlideListItem> + </div> + </SlideList> </Drawer> <div className={classes.toolbar} /> <Drawer @@ -176,6 +230,20 @@ const PresentationEditorPage: React.FC = () => { <Content leftDrawerWidth={leftDrawerWidth} rightDrawerWidth={rightDrawerWidth}> <SlideEditor /> </Content> + <Menu + keepMounted + open={contextState.mouseY !== null} + onClose={handleClose} + anchorReference="anchorPosition" + anchorPosition={ + contextState.mouseY !== null && contextState.mouseX !== null + ? { top: contextState.mouseY, left: contextState.mouseX } + : undefined + } + > + <MenuItem onClick={handleDuplicateSlide}>Duplicera</MenuItem> + <RemoveMenuItem onClick={handleRemoveSlide}>Ta bort</RemoveMenuItem> + </Menu> </PresentationEditorContainer> ) } diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx index 6791ce54..b0834e35 100644 --- a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx +++ b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx @@ -117,7 +117,7 @@ const CompetitionSettings: React.FC = () => { {/*TODO: fixa så cities laddar in i statet likt i CompetitionManager*/} <Select value={cities.find((city) => city.id === competition.city_id)?.name || ''} - label="RegionSelect" + label="Region" onChange={handleChange} > {cities.map((city) => ( diff --git a/client/src/pages/presentationEditor/styled.tsx b/client/src/pages/presentationEditor/styled.tsx index 14b173ce..d1f05d6b 100644 --- a/client/src/pages/presentationEditor/styled.tsx +++ b/client/src/pages/presentationEditor/styled.tsx @@ -1,4 +1,4 @@ -import { Button, ListItem, Toolbar } from '@material-ui/core' +import { Button, List, ListItem, Toolbar } from '@material-ui/core' import styled from 'styled-components' export const ToolBarContainer = styled(Toolbar)` @@ -16,6 +16,14 @@ export const ViewButtonGroup = styled.div` flex-direction: row; ` +export const SlideList = styled(List)` + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 0px; +` + export const SlideListItem = styled(ListItem)` text-align: center; height: 60px; -- GitLab