u
This commit is contained in:
@@ -1,8 +1,161 @@
|
||||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
import { Tile } from './Tile';
|
||||
import { Component } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import DragHandleIcon from '@mui/icons-material/DragHandle';
|
||||
import AccountTreeIcon from '@mui/icons-material/AccountTree';
|
||||
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
|
||||
import { Tile, tileBaseSx } from './Tile';
|
||||
|
||||
/**
|
||||
* Top edit band (upper third) with a move handle on the left and a tree
|
||||
* (drop-into-subcategory) handle on the right.
|
||||
*/
|
||||
function TopBand() {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '16.66%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
px: 0.5,
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
className="sortable-handle"
|
||||
size="small"
|
||||
aria-label="Verschieben"
|
||||
sx={{ cursor: 'grab', '&:active': { cursor: 'grabbing' } }}
|
||||
>
|
||||
<DragHandleIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
className="sortable-tree"
|
||||
size="small"
|
||||
aria-label="In Unterkategorie ablegen"
|
||||
sx={{ cursor: 'grab', '&:active': { cursor: 'grabbing' } }}
|
||||
>
|
||||
<AccountTreeIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared grey name band spanning the middle third.
|
||||
*/
|
||||
function NameBand({ label, nameInput }) {
|
||||
if (label == null) return null;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: '33.33%',
|
||||
bottom: '33.33%',
|
||||
left: 0,
|
||||
right: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
bgcolor: 'grey.300',
|
||||
px: 1,
|
||||
}}
|
||||
>
|
||||
{nameInput ?? (
|
||||
<Typography
|
||||
variant="body2"
|
||||
fontWeight={600}
|
||||
noWrap
|
||||
sx={{ lineHeight: 1.2, color: 'text.primary' }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bottom edit band with left/right chevron reorder buttons and a center delete.
|
||||
*/
|
||||
function EditBand({ onMoveLeft, onMoveRight, onDelete, canLeft, canRight }) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '16.66%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
px: 0.5,
|
||||
bgcolor: 'grey.400',
|
||||
}}
|
||||
>
|
||||
<IconButton className="sortable-handle-btn" size="small" aria-label="Nach links verschieben" disabled={!canLeft} onClick={onMoveLeft}>
|
||||
<ChevronLeftIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
<IconButton className="sortable-handle-btn" size="small" aria-label="Löschen" onClick={onDelete}>
|
||||
<DeleteOutlinedIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
<IconButton className="sortable-handle-btn" size="small" aria-label="Nach rechts verschieben" disabled={!canRight} onClick={onMoveRight}>
|
||||
<ChevronRightIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Category tile (normal mode): no icon, click navigates to the category.
|
||||
*/
|
||||
export class CategoryTile extends Tile {
|
||||
renderIcon() {
|
||||
return <FolderIcon color="primary" sx={{ fontSize: 40 }} />;
|
||||
return null;
|
||||
}
|
||||
|
||||
renderLabel() {
|
||||
const { label, nameInput } = this.props;
|
||||
return <NameBand label={label} nameInput={nameInput} />;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Category tile for edit mode: no ButtonBase (no ripple, no click navigation),
|
||||
* always shows the bottom edit band with chevron reorder/delete actions.
|
||||
*/
|
||||
export class CategoryEditTile extends Component {
|
||||
render() {
|
||||
const { label, nameInput, editBand, sx, ...rest } = this.props;
|
||||
return (
|
||||
<Box
|
||||
{...rest}
|
||||
sx={{
|
||||
...tileBaseSx,
|
||||
cursor: 'default',
|
||||
position: 'relative',
|
||||
'&:hover': { bgcolor: 'background.paper', boxShadow: 0 },
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<TopBand />
|
||||
<NameBand label={label} nameInput={nameInput} />
|
||||
<EditBand
|
||||
onMoveLeft={editBand.onMoveLeft}
|
||||
onMoveRight={editBand.onMoveRight}
|
||||
onDelete={editBand.onDelete}
|
||||
canLeft={editBand.canLeft}
|
||||
canRight={editBand.canRight}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user