@mui/material#SpeedDialIcon TypeScript Examples

The following examples show how to use @mui/material#SpeedDialIcon. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TransactionList.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function TransactionList({ group }) {
    const [speedDialOpen, setSpeedDialOpen] = useState(false);
    const toggleSpeedDial = () => setSpeedDialOpen((currValue) => !currValue);

    const [showTransferCreateDialog, setShowTransferCreateDialog] = useState(false);
    const [showPurchaseCreateDialog, setShowPurchaseCreateDialog] = useState(false);
    const transactions = useRecoilValue(transactionsSeenByUser(group.id));
    const currentUser = useRecoilValue(userData);
    const userPermissions = useRecoilValue(currUserPermissions(group.id));
    const userAccounts = useRecoilValue(accountsOwnedByUser({ groupID: group.id, userID: currentUser.id }));
    const groupAccountMap = useRecoilValue(accountIDsToName(group.id));

    const theme: Theme = useTheme();
    const isSmallScreen = useMediaQuery(theme.breakpoints.down("md"));

    const [filteredTransactions, setFilteredTransactions] = useState([]);

    const [searchValue, setSearchValue] = useState("");

    const [sortMode, setSortMode] = useState("last_changed"); // last_changed, description, value, billed_at

    useEffect(() => {
        let filtered = transactions;
        if (searchValue != null && searchValue !== "") {
            filtered = transactions.filter((t) => t.filter(searchValue, groupAccountMap));
        }
        filtered = [...filtered].sort(getTransactionSortFunc(sortMode));

        setFilteredTransactions(filtered);
    }, [searchValue, setFilteredTransactions, sortMode, transactions, userAccounts]);

    useTitle(`${group.name} - Transactions`);

    const openPurchaseCreateDialog = () => {
        setShowPurchaseCreateDialog(true);
    };

    const openTransferCreateDialog = () => {
        setShowTransferCreateDialog(true);
    };

    return (
        <>
            <MobilePaper>
                <Box
                    sx={{
                        display: "flex",
                        flexDirection: { xs: "column", sm: "column", md: "row", lg: "row" },
                        alignItems: { md: "flex-end" },
                        pl: "16px",
                        justifyContent: "space-between",
                    }}
                >
                    <Box sx={{ display: "flex-item" }}>
                        <Box sx={{ minWidth: "56px", pt: "16px" }}>
                            <SearchIcon sx={{ color: "action.active" }} />
                        </Box>
                        <Input
                            value={searchValue}
                            onChange={(e) => setSearchValue(e.target.value)}
                            placeholder="Search…"
                            inputProps={{
                                "aria-label": "search",
                            }}
                            sx={{ pt: "16px" }}
                            endAdornment={
                                <InputAdornment position="end">
                                    <IconButton
                                        aria-label="clear search input"
                                        onClick={(e) => setSearchValue("")}
                                        edge="end"
                                    >
                                        <Clear />
                                    </IconButton>
                                </InputAdornment>
                            }
                        />
                        <FormControl variant="standard" sx={{ minWidth: 120, ml: 3 }}>
                            <InputLabel id="select-sort-by-label">Sort by</InputLabel>
                            <Select
                                labelId="select-sort-by-label"
                                id="select-sort-by"
                                label="Sort by"
                                onChange={(evt) => setSortMode(evt.target.value)}
                                value={sortMode}
                            >
                                <MenuItem value="last_changed">Last changed</MenuItem>
                                <MenuItem value="description">Description</MenuItem>
                                <MenuItem value="value">Value</MenuItem>
                                <MenuItem value="billed_at">Date</MenuItem>
                            </Select>
                        </FormControl>
                    </Box>
                    {!isSmallScreen && (
                        <Box sx={{ display: "flex-item" }}>
                            <div style={{ padding: "8px" }}>
                                <Add color="primary" />
                            </div>
                            <Tooltip title="Create Purchase">
                                <IconButton color="primary" onClick={openPurchaseCreateDialog}>
                                    <PurchaseIcon />
                                </IconButton>
                            </Tooltip>
                            <Tooltip title="Create Transfer">
                                <IconButton color="primary" onClick={openTransferCreateDialog}>
                                    <TransferIcon />
                                </IconButton>
                            </Tooltip>
                        </Box>
                    )}
                </Box>
                <Divider sx={{ mt: 1 }} />
                <List>
                    {transactions.length === 0 ? (
                        <Alert severity="info">No Transactions</Alert>
                    ) : (
                        filteredTransactions.map((transaction) => (
                            <TransactionListEntry key={transaction.id} group={group} transaction={transaction} />
                        ))
                    )}
                </List>
                <TransferCreateModal
                    group={group}
                    show={showTransferCreateDialog}
                    onClose={(evt, reason) => {
                        if (reason !== "backdropClick") {
                            setShowTransferCreateDialog(false);
                        }
                    }}
                />
                <PurchaseCreateModal
                    group={group}
                    show={showPurchaseCreateDialog}
                    onClose={(evt, reason) => {
                        if (reason !== "backdropClick") {
                            setShowPurchaseCreateDialog(false);
                        }
                    }}
                />
            </MobilePaper>
            {userPermissions.can_write && (
                <SpeedDial
                    ariaLabel="Create Account"
                    sx={{ position: "fixed", bottom: 20, right: 20 }}
                    icon={<SpeedDialIcon />}
                    // onClose={() => setSpeedDialOpen(false)}
                    // onOpen={() => setSpeedDialOpen(true)}
                    onClick={toggleSpeedDial}
                    open={speedDialOpen}
                >
                    <SpeedDialAction
                        icon={<PurchaseIcon />}
                        tooltipTitle="Purchase"
                        tooltipOpen
                        onClick={openPurchaseCreateDialog}
                    />
                    <SpeedDialAction
                        icon={<TransferIcon />}
                        tooltipTitle="Transfer"
                        tooltipOpen
                        onClick={openTransferCreateDialog}
                    />
                </SpeedDial>
            )}
        </>
    );
}
Example #2
Source File: AccountList.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function AccountList({ group }) {
    const [speedDialOpen, setSpeedDialOpen] = useState(false);
    const toggleSpeedDial = () => setSpeedDialOpen((currValue) => !currValue);

    const [showPersonalAccountCreationModal, setShowPersonalAccountCreationModal] = useState(false);
    const [showClearingAccountCreationModal, setShowClearingAccountCreationModal] = useState(false);

    const [activeTab, setActiveTab] = useState("personal");
    const [searchValuePersonal, setSearchValuePersonal] = useState("");
    const [searchValueClearing, setSearchValueClearing] = useState("");

    const [showPersonalAccountEditModal, setShowPersonalAccountEditModal] = useState(false);
    const [showClearingAccountEditModal, setShowClearingAccountEditModal] = useState(false);
    const [clearingAccountToCopy, setClearingAccountToCopy] = useState(undefined);
    const [accountToEdit, setAccountToEdit] = useState(null);
    const [clearingAccountToEdit, setClearingAccountToEdit] = useState(null);
    const setAccounts = useSetRecoilState(groupAccounts(group.id));
    const personalAccounts = useRecoilValue(personalAccountsSeenByUser(group.id));
    const clearingAccounts = useRecoilValue(clearingAccountsSeenByUser(group.id));
    const allAccounts = useRecoilValue(accountsSeenByUser(group.id));
    const [accountToDelete, setAccountToDelete] = useState(null);
    const userPermissions = useRecoilValue(currUserPermissions(group.id));
    const currentUser = useRecoilValue(userData);
    const memberIDToUsername = useRecoilValue(groupMemberIDsToUsername(group.id));

    const [filteredPersonalAccounts, setFilteredPersonalAccounts] = useState([]);
    const [filteredClearingAccounts, setFilteredClearingAccounts] = useState([]);
    useEffect(() => {
        if (searchValuePersonal != null && searchValuePersonal !== "") {
            setFilteredPersonalAccounts(
                personalAccounts.filter((t) => {
                    return (
                        t.name.toLowerCase().includes(searchValuePersonal.toLowerCase()) ||
                        t.description.toLowerCase().includes(searchValuePersonal.toLowerCase())
                    );
                })
            );
        } else {
            return setFilteredPersonalAccounts(personalAccounts);
        }
    }, [personalAccounts, searchValuePersonal, setFilteredPersonalAccounts]);

    useEffect(() => {
        if (searchValueClearing != null && searchValueClearing !== "") {
            setFilteredClearingAccounts(
                clearingAccounts.filter((t) => {
                    return (
                        t.name.toLowerCase().includes(searchValueClearing.toLowerCase()) ||
                        t.description.toLowerCase().includes(searchValueClearing.toLowerCase())
                    );
                })
            );
        } else {
            return setFilteredClearingAccounts(clearingAccounts);
        }
    }, [clearingAccounts, searchValueClearing, setFilteredClearingAccounts]);

    useTitle(`${group.name} - Accounts`);

    const openAccountEdit = (account) => {
        setAccountToEdit(account);
        setShowPersonalAccountEditModal(true);
    };

    const closeAccountEdit = (evt, reason) => {
        if (reason !== "backdropClick") {
            setShowPersonalAccountEditModal(false);
            setAccountToEdit(null);
        }
    };

    const openClearingAccountEdit = (account) => {
        setClearingAccountToEdit(account);
        setShowClearingAccountEditModal(true);
    };

    const closeClearingAccountEdit = (evt, reason) => {
        if (reason !== "backdropClick") {
            setShowClearingAccountEditModal(false);
            setClearingAccountToEdit(null);
        }
    };

    const confirmDeleteAccount = () => {
        if (accountToDelete !== null) {
            deleteAccount({ accountID: accountToDelete })
                .then((account) => {
                    updateAccount(account, setAccounts);
                    setAccountToDelete(null);
                })
                .catch((err) => {
                    toast.error(err);
                });
        }
    };

    const openCreateDialog = () => {
        setClearingAccountToCopy(undefined);
        setShowClearingAccountCreationModal(true);
    };

    const copyClearingAccount = (account) => {
        setClearingAccountToCopy(account);
        setShowClearingAccountCreationModal(true);
    };

    return (
        <>
            <MobilePaper>
                <TabContext value={activeTab}>
                    <Box sx={{ borderBottom: 1, borderColor: "divider" }}>
                        <TabList onChange={(e, newValue) => setActiveTab(newValue)} centered>
                            <Tab
                                value="personal"
                                label={
                                    <TextBadge badgeContent={personalAccounts.length} color="primary">
                                        <span>Personal Accounts</span>
                                    </TextBadge>
                                }
                            />
                            <Tab
                                label={
                                    <TextBadge badgeContent={clearingAccounts.length} color="primary">
                                        <span>Clearing Accounts</span>
                                    </TextBadge>
                                }
                                value="clearing"
                            />
                        </TabList>
                    </Box>
                    <TabPanel value="personal">
                        <List>
                            {personalAccounts.length === 0 ? (
                                <Alert severity="info">No Accounts</Alert>
                            ) : (
                                <>
                                    <ListItem>
                                        <Input
                                            value={searchValuePersonal}
                                            onChange={(e) => setSearchValuePersonal(e.target.value)}
                                            placeholder="Search…"
                                            inputProps={{
                                                "aria-label": "search",
                                            }}
                                            endAdornment={
                                                <InputAdornment position="end">
                                                    <IconButton
                                                        aria-label="clear search input"
                                                        onClick={(e) => setSearchValuePersonal("")}
                                                        edge="end"
                                                    >
                                                        <Clear />
                                                    </IconButton>
                                                </InputAdornment>
                                            }
                                        />
                                    </ListItem>
                                    <Divider />
                                    {filteredPersonalAccounts.map((account) => (
                                        <ListItem sx={{ padding: 0 }} key={account.id}>
                                            <ListItemLink to={`/groups/${group.id}/accounts/${account.id}`}>
                                                <ListItemText
                                                    primary={
                                                        <div>
                                                            <span>{account.name}</span>
                                                            {account.owning_user_id === currentUser.id ? (
                                                                <span>
                                                                    , owned by{" "}
                                                                    <Chip
                                                                        size="small"
                                                                        component="span"
                                                                        color="primary"
                                                                        label="you"
                                                                    />
                                                                </span>
                                                            ) : (
                                                                account.owning_user_id !== null && (
                                                                    <span>
                                                                        , owned by{" "}
                                                                        <Chip
                                                                            size="small"
                                                                            component="span"
                                                                            color="secondary"
                                                                            label={
                                                                                memberIDToUsername[
                                                                                    account.owning_user_id
                                                                                ]
                                                                            }
                                                                        />
                                                                    </span>
                                                                )
                                                            )}
                                                        </div>
                                                    }
                                                    secondary={account.description}
                                                />
                                            </ListItemLink>
                                            {userPermissions.can_write && (
                                                <ListItemSecondaryAction>
                                                    <IconButton
                                                        color="primary"
                                                        onClick={() => openAccountEdit(account)}
                                                    >
                                                        <Edit />
                                                    </IconButton>
                                                    <IconButton
                                                        color="error"
                                                        onClick={() => setAccountToDelete(account.id)}
                                                    >
                                                        <Delete />
                                                    </IconButton>
                                                </ListItemSecondaryAction>
                                            )}
                                        </ListItem>
                                    ))}
                                </>
                            )}
                        </List>
                        {userPermissions.can_write && (
                            <>
                                <Grid container justifyContent="center">
                                    <Tooltip title="Create Personal Account">
                                        <IconButton
                                            color="primary"
                                            onClick={() => setShowPersonalAccountCreationModal(true)}
                                        >
                                            <Add />
                                        </IconButton>
                                    </Tooltip>
                                </Grid>
                                <CreateAccountModal
                                    show={showPersonalAccountCreationModal}
                                    onClose={(evt, reason) => {
                                        if (reason !== "backdropClick") {
                                            setShowPersonalAccountCreationModal(false);
                                        }
                                    }}
                                    group={group}
                                />
                                <EditAccountModal
                                    show={showPersonalAccountEditModal}
                                    onClose={closeAccountEdit}
                                    account={accountToEdit}
                                    group={group}
                                />
                            </>
                        )}
                    </TabPanel>
                    <TabPanel value="clearing">
                        <List>
                            {clearingAccounts.length === 0 ? (
                                <Alert severity="info">No Accounts</Alert>
                            ) : (
                                <>
                                    <ListItem>
                                        <Input
                                            value={searchValueClearing}
                                            onChange={(e) => setSearchValueClearing(e.target.value)}
                                            placeholder="Search…"
                                            inputProps={{
                                                "aria-label": "search",
                                            }}
                                            endAdornment={
                                                <InputAdornment position="end">
                                                    <IconButton
                                                        aria-label="clear search input"
                                                        onClick={(e) => setSearchValueClearing("")}
                                                        edge="end"
                                                    >
                                                        <Clear />
                                                    </IconButton>
                                                </InputAdornment>
                                            }
                                        />
                                    </ListItem>
                                    <Divider />
                                    {filteredClearingAccounts.map((account) => (
                                        <ListItem sx={{ padding: 0 }} key={account.id}>
                                            <ListItemLink to={`/groups/${group.id}/accounts/${account.id}`}>
                                                <ListItemText primary={account.name} secondary={account.description} />
                                            </ListItemLink>
                                            {userPermissions.can_write && (
                                                <ListItemSecondaryAction>
                                                    <IconButton
                                                        color="primary"
                                                        onClick={() => openClearingAccountEdit(account)}
                                                    >
                                                        <Edit />
                                                    </IconButton>
                                                    <IconButton
                                                        color="primary"
                                                        onClick={() => copyClearingAccount(account)}
                                                    >
                                                        <ContentCopy />
                                                    </IconButton>
                                                    <IconButton
                                                        color="error"
                                                        onClick={() => setAccountToDelete(account.id)}
                                                    >
                                                        <Delete />
                                                    </IconButton>
                                                </ListItemSecondaryAction>
                                            )}
                                        </ListItem>
                                    ))}
                                </>
                            )}
                        </List>
                        {userPermissions.can_write && (
                            <>
                                <Grid container justifyContent="center">
                                    <Tooltip title="Create Clearing Account">
                                        <IconButton color="primary" onClick={openCreateDialog}>
                                            <Add />
                                        </IconButton>
                                    </Tooltip>
                                </Grid>
                                <CreateClearingAccountModal
                                    show={showClearingAccountCreationModal}
                                    onClose={(evt, reason) => {
                                        if (reason !== "backdropClick") {
                                            setShowClearingAccountCreationModal(false);
                                        }
                                    }}
                                    initialValues={clearingAccountToCopy}
                                    group={group}
                                />
                                <EditClearingAccountModal
                                    show={showClearingAccountEditModal}
                                    onClose={closeClearingAccountEdit}
                                    account={clearingAccountToEdit}
                                    group={group}
                                />
                            </>
                        )}
                    </TabPanel>
                </TabContext>
            </MobilePaper>
            {userPermissions.can_write && (
                <>
                    <SpeedDial
                        ariaLabel="Create Account"
                        sx={{ position: "fixed", bottom: 20, right: 20 }}
                        icon={<SpeedDialIcon />}
                        // onClose={() => setSpeedDialOpen(false)}
                        // onOpen={() => setSpeedDialOpen(true)}
                        onClick={toggleSpeedDial}
                        open={speedDialOpen}
                    >
                        <SpeedDialAction
                            icon={<PersonalAccountIcon />}
                            tooltipTitle="Personal"
                            tooltipOpen
                            onClick={() => setShowPersonalAccountCreationModal(true)}
                        />
                        <SpeedDialAction
                            icon={<ClearingAccountIcon />}
                            tooltipTitle="Clearing"
                            tooltipOpen
                            onClick={openCreateDialog}
                        />
                    </SpeedDial>

                    <Dialog maxWidth="xs" aria-labelledby="confirmation-dialog-title" open={accountToDelete !== null}>
                        <DialogTitle id="confirmation-dialog-title">Confirm delete account</DialogTitle>
                        <DialogContent dividers>
                            Are you sure you want to delete the account "
                            {allAccounts.find((acc) => acc.id === accountToDelete)?.name}"
                        </DialogContent>
                        <DialogActions>
                            <Button autoFocus onClick={() => setAccountToDelete(null)} color="primary">
                                Cancel
                            </Button>
                            <Button onClick={confirmDeleteAccount} color="error">
                                Ok
                            </Button>
                        </DialogActions>
                    </Dialog>
                </>
            )}
        </>
    );
}