Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Apps] New accordion groups, autocomplete search to filter by existing set of all users with App permissions #172

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
45292a0
Access user guide: collapse everything but current accordion on click…
savathoon Oct 28, 2024
66b3d65
break out app group header component for readability
savathoon Oct 28, 2024
0ed08ee
update paths, set min width on header to prevent icon overlap on smal…
savathoon Oct 28, 2024
c440947
Break out admin action button group into sub component on apps page, …
savathoon Oct 28, 2024
2f7c44d
App detail: remove duplicate components, replace with EmptyListEntry …
savathoon Oct 29, 2024
f63e77d
replace duplicate empty list entries with emptylistentry component
savathoon Oct 29, 2024
d4a6ec0
Add props for adding custom empty list text
savathoon Oct 29, 2024
1719825
App page: initial demo accordion, fix missing admin group button
savathoon Oct 29, 2024
813fcd4
[feat] dark mode and theme toggle (#174)
amyjchen Oct 29, 2024
3173e61
make theme toggle minimize when nav is minimized
amyjchen Oct 29, 2024
fc557e5
figure out why table rows are not 100% width with accordion component
savathoon Oct 30, 2024
082cbd1
full-width accordion list
savathoon Oct 30, 2024
7367f5f
add demo of owner group card for accordion list
savathoon Oct 30, 2024
4ed8ee6
Merge branch '2024-hackweek' into sava/more-components
savathoon Oct 30, 2024
3c51142
[Group Detail] Update the groups member page to add spacing and wrap …
savathoon Oct 30, 2024
fed33e7
Merge branch '2024-hackweek' into sava/more-components
savathoon Oct 30, 2024
ecac23f
[feat] Table Top Bar Component (#177)
amyjchen Oct 30, 2024
fa37b58
figure out why this thing hates being full width of the parent compon…
savathoon Oct 30, 2024
cdfa264
Merge branch '2024-hackweek' into sava/more-components
savathoon Oct 30, 2024
1aa0aa8
update owner group accordion on app group page
savathoon Oct 30, 2024
a50ceaa
[fix] update user avatars to have adequate contrast across themes (#178)
amyjchen Oct 31, 2024
01f5b77
[fix] dark mode bugs (#179)
amyjchen Oct 31, 2024
9015a9c
fix missing key
amyjchen Oct 31, 2024
2a3f548
v0 of trying to filter members down to unique in list groups
savathoon Oct 31, 2024
8809feb
merge
savathoon Oct 31, 2024
c0988d4
flex jank
savathoon Oct 31, 2024
d1158ad
merge back changes in app/detail/index
savathoon Oct 31, 2024
166b4d2
controlled accordion but only kinda
savathoon Oct 31, 2024
69727e4
fix imports
savathoon Nov 1, 2024
f4b3dbc
autocomplete with members
savathoon Nov 1, 2024
fe70d9c
autocomplete
savathoon Nov 1, 2024
437bdae
add back dedupe
savathoon Nov 1, 2024
418f806
add optional header description to accordion list group
savathoon Nov 1, 2024
be55f39
[feat] Update Headers (#180)
amyjchen Nov 1, 2024
f43bcfd
[Groups] Add styles to wrap group name in header (#183)
savathoon Nov 1, 2024
fb5bc98
merge
savathoon Nov 1, 2024
e5108aa
merge conflict fixings
savathoon Nov 1, 2024
8e46b5d
Apps: user filter options now sorted
savathoon Nov 1, 2024
fc0e6e0
Hide title and description if accordion list is empty
savathoon Nov 1, 2024
3bdc926
update copy
savathoon Nov 1, 2024
dfaf96c
oops
savathoon Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 155 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import {Link as RouterLink, Route, Routes} from 'react-router-dom';

import {styled} from '@mui/material/styles';
import {createTheme, styled, ThemeProvider} from '@mui/material/styles';
import Link from '@mui/material/Link';
import MuiDrawer from '@mui/material/Drawer';
import Box from '@mui/material/Box';
Expand Down Expand Up @@ -37,6 +37,19 @@ import ReadTag from './pages/tags/Read';
import ReadUser from './pages/users/Read';
import {useCurrentUser} from './authentication';
import ReadRequest from './pages/requests/Read';
import {
alpha,
CssBaseline,
PaletteMode,
Stack,
ToggleButton,
ToggleButtonGroup,
Tooltip,
useMediaQuery,
useTheme,
} from '@mui/material';
import {DarkMode, LightMode, Monitor} from '@mui/icons-material';
import {lightGreen, red, yellow} from '@mui/material/colors';

const drawerWidth: number = 240;

Expand Down Expand Up @@ -88,14 +101,72 @@ const Drawer = styled(MuiDrawer, {
},
}));

function Dashboard() {
function ThemeToggle({setThemeMode, condensed}: {setThemeMode: (theme: PaletteMode) => void; condensed: boolean}) {
const [storedTheme, setStoredTheme] = React.useState(
localStorage.getItem('user-set-color-scheme') as 'light' | 'dark' | null,
);
const currentTheme = useTheme();
const systemTheme = useMediaQuery('(prefers-color-scheme: dark)') ? 'dark' : 'light';

const handleThemeOverride = (theme: PaletteMode) => {
setThemeMode(theme);
localStorage.setItem('user-set-color-scheme', theme);
setStoredTheme(theme);
};

const handleSystemDefault = () => {
setThemeMode(systemTheme);
localStorage.removeItem('user-set-color-scheme');
setStoredTheme(null);
};

return (
<ToggleButtonGroup size="small">
{(currentTheme.palette.mode != 'light' || !condensed) && (
<Tooltip title="Light Mode">
<ToggleButton
value="left"
selected={storedTheme === 'light'}
onClick={() => handleThemeOverride('light')}
aria-label="Light mode">
<LightMode />
</ToggleButton>
</Tooltip>
)}
{!condensed && (
<Tooltip title="System Default">
<ToggleButton
value="center"
selected={storedTheme == null}
onClick={handleSystemDefault}
aria-label="System Default">
<Monitor />
</ToggleButton>
</Tooltip>
)}
{(currentTheme.palette.mode != 'dark' || !condensed) && (
<Tooltip title="Dark Mode">
<ToggleButton
value="right"
selected={storedTheme === 'dark'}
onClick={() => handleThemeOverride('dark')}
aria-label="Dark mode">
<DarkMode />
</ToggleButton>
</Tooltip>
)}
</ToggleButtonGroup>
);
}

function Dashboard({setThemeMode}: {setThemeMode: (theme: PaletteMode) => void}) {
const [open, setOpen] = React.useState(true);
const toggleDrawer = () => {
setOpen(!open);
};

return (
<Box sx={{display: 'flex'}}>
<Box sx={{display: 'flex', minWidth: '20rem', overflowX: 'hidden'}}>
<AppBar position="absolute" open={open}>
<Toolbar
sx={{
Expand Down Expand Up @@ -137,7 +208,7 @@ function Dashboard() {
textDecoration: 'none',
}}>
<Avatar src="/logo-square.png" variant="square" />
<Typography component="h1" variant="h5" sx={{px: 2}}>
<Typography component="h1" variant="h5" sx={{px: 2}} color="text.accent">
ACCESS
</Typography>
</Link>
Expand All @@ -149,12 +220,15 @@ function Dashboard() {
<List component="nav">
<NavItems open={open} />
</List>
<Stack marginTop="auto" p={2}>
<ThemeToggle setThemeMode={setThemeMode} condensed={!open} />
</Stack>
</Drawer>
<Box
component="main"
sx={{
backgroundColor: (theme) =>
theme.palette.mode === 'light' ? theme.palette.grey[100] : theme.palette.grey[900],
theme.palette.mode === 'light' ? theme.palette.grey[200] : theme.palette.grey[800],
flexGrow: 1,
height: '100vh',
overflow: 'auto',
Expand Down Expand Up @@ -189,6 +263,81 @@ function Dashboard() {
}

export default function App() {
const storedTheme = localStorage.getItem('user-set-color-scheme') as 'light' | 'dark' | null;
const systemTheme = useMediaQuery('(prefers-color-scheme: dark)') ? 'dark' : 'light';
const initialMode = storedTheme ?? systemTheme;
const [mode, setMode] = React.useState<PaletteMode>(initialMode);

// See https://discord.com/branding
let theme = React.useMemo(() => {
const base = createTheme({
palette: {
mode,
primary: {
main: '#5865F2',
light: '#A5B2FF',
},
secondary: {
main: '#EB459E',
},
error: {
main: '#ED4245',
},
warning: {
main: '#FEE75C',
},
success: {
main: '#57F287',
},
text: {
accent: mode === 'light' ? '#5865F2' : '#A5B2FF',
},
},
components: {
MuiChip: {
styleOverrides: {
colorPrimary: ({ownerState, theme}) => ({
...(ownerState.variant === 'outlined' &&
ownerState.color === 'primary' && {
color: theme.palette.text.accent,
borderColor: theme.palette.text.accent,
}),
}),
deleteIcon: ({ownerState, theme}) => ({
...(ownerState.variant === 'outlined' &&
ownerState.color === 'primary' && {
color: theme.palette.text.accent,
}),
}),
},
},
},
});
return createTheme(base, {
palette: {
highlight: {
success: base.palette.augmentColor({
color: {main: mode === 'light' ? lightGreen[100] : alpha(lightGreen[500], 0.3)},
name: 'success',
}),
warning: base.palette.augmentColor({
color: {main: mode === 'light' ? yellow[100] : alpha(yellow[500], 0.3)},
name: 'warning',
}),
danger: base.palette.augmentColor({
color: {main: mode === 'light' ? red[100] : alpha(red[500], 0.3)},
name: 'danger',
}),
},
},
});
}, [mode]);

useCurrentUser();
return <Dashboard />;
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Dashboard setThemeMode={setMode} />
</ThemeProvider>
);
}
33 changes: 33 additions & 0 deletions src/components/AvatarButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {Avatar, ButtonBase, Typography} from '@mui/material';
import {ReactNode} from 'react';

interface AvatarButtonProps {
icon: ReactNode;
text?: string;
strikethrough?: boolean;
onClick?: () => void;
}

export default function AvatarButton({icon, text, strikethrough, onClick}: AvatarButtonProps) {
return (
<ButtonBase
disabled={onClick == null}
sx={{
display: 'flex',
flexDirection: 'column',
gap: 0.5,
p: 0.5,
borderRadius: 2,
width: 100,
wordBreak: 'break-word',
}}
onClick={onClick}>
<Avatar sx={{bgcolor: 'primary.main'}}>{icon}</Avatar>
{text && (
<Typography variant="body2" sx={{...(strikethrough && {textDecoration: 'line-through'})}}>
{text}
</Typography>
)}
</ButtonBase>
);
}
2 changes: 1 addition & 1 deletion src/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Typography from '@mui/material/Typography';

import Link, {LinkProps} from '@mui/material/Link';
import Link from '@mui/material/Link';
import {Link as RouterLink, useLocation} from 'react-router-dom';

export default function Crumbs() {
Expand Down
44 changes: 44 additions & 0 deletions src/components/BulkRenewalDataGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {darken, lighten, PaletteColor, styled} from '@mui/material';
import {DataGrid} from '@mui/x-data-grid';

const getHoverBackgroundColor = (color: PaletteColor, mode: string) => (mode === 'dark' ? color.dark : color.light);

const getSelectedBackgroundColor = (color: PaletteColor, mode: string) =>
mode === 'dark' ? darken(color.dark, 0.5) : lighten(color.light, 0.5);

const getSelectedHoverBackgroundColor = (color: PaletteColor, mode: string) =>
mode === 'dark' ? darken(color.dark, 0.4) : lighten(color.light, 0.4);

const BulkRenewalDataGrid = styled(DataGrid)(
({
theme: {
palette: {highlight, mode},
},
}) => ({
'& .super-app-theme--Expired': {
backgroundColor: highlight.danger.main,
'&:hover': {
backgroundColor: getHoverBackgroundColor(highlight.danger, mode),
},
'&.Mui-selected': {
backgroundColor: getSelectedBackgroundColor(highlight.danger, mode),
'&:hover': {
backgroundColor: getSelectedHoverBackgroundColor(highlight.danger, mode),
},
},
},
'& .super-app-theme--Soon': {
backgroundColor: highlight.warning.main,
'&:hover': {
backgroundColor: getHoverBackgroundColor(highlight.warning, mode),
},
'&.Mui-selected': {
backgroundColor: getSelectedBackgroundColor(highlight.warning, mode),
'&:hover': {
backgroundColor: getSelectedHoverBackgroundColor(highlight.warning, mode),
},
},
},
}),
);
export default BulkRenewalDataGrid;
Loading