Skip to content

Commit

Permalink
Merge pull request #171 from Vincit/feature/new-theme
Browse files Browse the repository at this point in the history
Made showRoomResources-option database saveable and fixed drawer headers
  • Loading branch information
villepynttari authored Jul 4, 2024
2 parents 440ab49 + 99e00fa commit 34073c7
Show file tree
Hide file tree
Showing 16 changed files with 296 additions and 38 deletions.
18 changes: 12 additions & 6 deletions backend/src/controllers/preferencesController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ describe('preferencesController', () => {
id: 'id'
};

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockedGetUserWithSubject.mockResolvedValueOnce({
subject: 'sub',
preferences: {
Expand Down Expand Up @@ -217,6 +219,8 @@ describe('preferencesController', () => {
});

test('Should set preferences to locals', async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockedUpdatePreferences.mockResolvedValueOnce({
subject: 'sub',
preferences: {
Expand All @@ -235,12 +239,14 @@ describe('preferencesController', () => {

expect(mockNext).toBeCalledTimes(1);
expect(mockNext).toBeCalledWith();
expect(mockResponse.locals?.preferences).toEqual({
building: {
id: mockResponse.locals?.buildingId,
name: mockResponse.locals?.buildingName
}
});
expect(mockResponse.locals?.preferences).toEqual(
expect.objectContaining({
building: {
id: mockResponse.locals?.buildingId,
name: mockResponse.locals?.buildingName
}
})
);
});
});
});
5 changes: 4 additions & 1 deletion backend/src/controllers/preferencesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const readPreferenceBody = () => {
try {
const building: BuildingData = req.body.building;
const favoriteRooms: Array<string> = req.body.fav_rooms;
const showRoomResources = req.body.showRoomResources;

if (!building || !building.id || !building.name) {
return responses.badRequest(req, res);
Expand All @@ -58,6 +59,7 @@ export const readPreferenceBody = () => {
res.locals.buildingId = building.id;
res.locals.buildingName = building.name;
res.locals.fav_rooms = favoriteRooms;
res.locals.showRoomResources = showRoomResources;
next();
} catch (err) {
next(err);
Expand Down Expand Up @@ -86,7 +88,8 @@ export const updatePreferencesToDatabase = () => {
latitude: res.locals.latitude,
longitude: res.locals.longitude
},
fav_rooms: res.locals.fav_rooms
fav_rooms: res.locals.fav_rooms,
showRoomResources: res.locals?.showRoomResources || false
};

if (!sub) {
Expand Down
4 changes: 4 additions & 0 deletions backend/src/models/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export const preferencesSchema = new Schema<Preferences>(
fav_rooms: {
required: false,
type: [String]
},
showRoomResources: {
required: false,
type: Boolean
}
},
{ _id: false }
Expand Down
3 changes: 2 additions & 1 deletion backend/src/routes/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export const router = express.Router();
router.get('/', controller.getPreferences(), (req, res) => {
res.status(200).json({
building: res.locals.preferences.building || {},
fav_rooms: res.locals.preferences.fav_rooms || []
fav_rooms: res.locals.preferences.fav_rooms || [],
showRoomResources: res.locals.preferences.showRoomResources || false
});
});

Expand Down
1 change: 1 addition & 0 deletions backend/src/types/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import buildingData from './buildingData';
type Preferences = {
building?: buildingData;
fav_rooms?: string[] | null | undefined;
showRoomResources?: boolean;
};

export default Preferences;
5 changes: 3 additions & 2 deletions frontend/src/components/BookingDrawer/BookingDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SwipeableEdgeDrawer, {
import { Room } from '../../types';
import { getTimeLeft, getTimeLeftMinutes2 } from '../util/TimeLeft';
import { theme } from '../../theme';
import BottomDrawer from '../BottomDrawer/BottomDrawer';

const MIN_DURATION = 15;

Expand Down Expand Up @@ -288,7 +289,7 @@ const BookingDrawer = (props: Props) => {
};

return (
<SwipeableEdgeDrawer
<BottomDrawer
headerTitle={getName(room)}
iconLeft={'AccessTime'}
iconRight={'Close'}
Expand Down Expand Up @@ -381,7 +382,7 @@ const BookingDrawer = (props: Props) => {
</Row>
</DrawerContent>
</Box>
</SwipeableEdgeDrawer>
</BottomDrawer>
);
};

Expand Down
209 changes: 209 additions & 0 deletions frontend/src/components/BottomDrawer/BottomDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import * as React from 'react';
import { Global } from '@emotion/react';
import { styled } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { grey } from '@mui/material/colors';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import { Drawer, IconButton, Stack } from '@mui/material';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CloseIcon from '@mui/icons-material/Close';
import MapIcon from '@mui/icons-material/Map';
import Person from '@mui/icons-material/Person';
import FilterListIcon from '@mui/icons-material/FilterList';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { COLORS } from '../../theme_2024';

export const drawerBleeding = 88;

const Root = styled('div')(({ theme }) => ({
height: '100%',
backgroundColor:
theme.palette.mode === 'light'
? grey[100]
: theme.palette.background.default
}));

const DrawerHeader = styled(Box)(({ theme }) => ({
padding: '24px',
display: 'flex',
justifyContent: 'center',
position: 'absolute',
top: -drawerBleeding,
borderTopLeftRadius: 40,
borderTopRightRadius: 40,
visibility: 'visible',
right: 0,
left: 0,
boxShadow: '0px -2px 4px rgba(205, 197, 197, 0.25)',
backgroundColor: '#fff'
}));

const FilterCounter = styled(Box)(({ theme }) => ({
borderRadius: 50,
display: 'flex',
width: '20px',
height: '20px',
fontstyle: 'normal',
fontWeight: 700,
fontSize: '16px',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
margin: '0 0 0 8px',
color: COLORS.BACKGROUND_PRIMARY,
backgroundColor: COLORS.ACCENT_BLUE
}));

const DrawerTitle = styled(Typography)(({ theme }) => ({
fontStyle: 'normal',
fontWeight: 'bold',
fontSize: '24px',
lineHeight: '24px',
whiteSpace: 'nowrap'
}));

export const DrawerContent = styled(Box)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
height: '100%',
margin: '0 24px 24px 24px',
width: 'calc(100% - 48px)',
maxWidth: '1000px'
}));

interface Props {
children: React.ReactChild;
iconLeft?: React.ReactNode;
iconRight?: React.ReactNode;
filterCount?: number;
headerTitle: String | undefined;
isOpen: boolean;
toggle: (open: boolean) => void;
disableSwipeToOpen: boolean;
mounted?: boolean;
}

const BottomDrawer = (props: Props) => {
const {
children,
headerTitle,
filterCount,
iconLeft,
isOpen,
toggle,
mounted
} = props;

const toggleDrawer = (newOpen: boolean) => () => {
toggle(newOpen);
};

let left;
let title;
let right;
let filters;

if (iconLeft === 'Map') {
left = <MapIcon sx={{ color: '#219653' }} />;
title = (
<DrawerTitle sx={{ color: '#219653' }}>{headerTitle}</DrawerTitle>
);
right = <CloseIcon />;
} else if (iconLeft === 'Person') {
left = <Person />;
title = <DrawerTitle>{headerTitle}</DrawerTitle>;
right = <CloseIcon />;
} else if (iconLeft === 'FilterList') {
left = <FilterListIcon />;
if (filterCount !== 0) {
filters = <FilterCounter>{filterCount}</FilterCounter>;
}

title = <DrawerTitle>{headerTitle}</DrawerTitle>;
if (isOpen) {
right = <ExpandMoreIcon />;
} else {
right = <ExpandLessIcon />;
}
} else {
left = <AccessTimeIcon />;
title = <DrawerTitle>{headerTitle}</DrawerTitle>;
right = <CloseIcon />;
}

let label;
if (iconLeft === 'FilterList') {
if (isOpen) {
label = 'reduce';
} else {
label = 'expand';
}
} else {
label = 'close';
}

const handleHeaderClick = () => {
if (headerTitle === 'Filters' && isOpen === true) {
toggle(false);
}
};

return (
<Root>
<CssBaseline />
<Global
styles={{
'.MuiDrawer-root > .MuiPaper-root': {
overflow: 'visible'
}
}}
/>
<Drawer
data-testid="BookingDrawer"
anchor="bottom"
open={isOpen}
onClose={toggleDrawer(false)}
keepMounted={mounted}
style={{
position: 'relative',
width: '100%',
maxWidth: '1000px'
}}
>
{headerTitle && headerTitle != '' ? (
<DrawerHeader onClick={handleHeaderClick}>
<Box
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
maxWidth: '1000px'
}}
>
{left}
<Stack direction={'row'}>
{title}
{filters}
</Stack>
<IconButton
onClick={toggleDrawer(false)}
aria-label={label}
>
{right}
</IconButton>
</Box>
</DrawerHeader>
) : (
''
)}
{children}
</Drawer>
</Root>
);
};

export default BottomDrawer;
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ describe('ChooseOfficeView', () => {
fireEvent.click(screen.getByText(TEST_BUILDINGS[1].name));

expect(updatePreferences as jest.Mock).toHaveBeenCalledWith({
building: TEST_BUILDINGS[1]
building: TEST_BUILDINGS[1],
showRoomResources: false
});
await waitFor(() => {
expect(mockedSetPreferences).toHaveBeenCalledWith({
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/components/ChooseOfficeView/ChooseOfficeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { updatePreferences } from '../../services/preferencesService';
import { Building, Preferences } from '../../types';
import CenteredProgress from '../util/CenteredProgress';
import { getBuildingsWithPosition } from '../../services/buildingService';
import { useUserSettings } from '../../contexts/UserSettingsContext';

type ChooseOfficeViewProps = {
buildings: Building[];
Expand Down Expand Up @@ -51,13 +52,16 @@ const ChooseOfficeView = (props: ChooseOfficeViewProps) => {
history.push('/');
};

const { expandedFeaturesAll } = useUserSettings();

const handlePreferencesSubmit = (buildingId: string) => {
const foundBuilding = buildings.find(
(building) => building.id === buildingId
);
if (foundBuilding) {
let newPrefs = preferences as Preferences;
newPrefs.building = foundBuilding;
newPrefs.showRoomResources = expandedFeaturesAll;
updatePreferences(newPrefs)
.then((savedPreferences) => {
setPreferences(savedPreferences);
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/MainView/MainView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import { Box } from '@mui/material';
import { getName } from '../../services/nameService';
import { useHistory } from 'react-router-dom';
import usePushNotificationRegistration from '../../hooks/usePushNotificationRegistration';
import { useUserSettings } from '../../contexts/UserSettingsContext';

const MainView = () => {
const [preferences, setPreferences] = useState<Preferences | undefined>();

const { preferences, setPreferences } = useUserSettings();
const [buildings, setBuildings] = useState<Building[]>([]);

const [name, setName] = useState<String>();
Expand All @@ -31,7 +31,9 @@ const MainView = () => {

useEffect(() => {
getPreferences()
.then(setPreferences)
.then((preferences) => {
setPreferences(preferences);
})
.catch((e) => {
// Redirected to login
console.log(e);
Expand Down
Loading

0 comments on commit 34073c7

Please sign in to comment.