Skip to content

Commit

Permalink
added optional fields in book room page
Browse files Browse the repository at this point in the history
  • Loading branch information
ali-ahnaf committed Sep 15, 2024
1 parent 49594b7 commit 30bae01
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 45 deletions.
73 changes: 62 additions & 11 deletions client/src/components/ChipInput.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,89 @@
import React, { useState } from 'react';
import { TextField, Chip, Box, Typography } from '@mui/material';
import { TextField, Chip, Box, Typography, SxProps, Theme } from '@mui/material';

export default function ChipInput() {
interface ChipInputProps {
id: string;
sx?: SxProps<Theme>;
value?: string;
disabled?: boolean;
onChange: (id: string, value: string[]) => void;
}

export default function ChipInput({ id, sx, onChange }: ChipInputProps) {
const [inputValue, setInputValue] = useState('');
const [chips, setChips] = useState<any[]>([]);

// Function to handle chip addition
const handleKeyDown = (event: any) => {
if (event.key === ' ' && inputValue.trim() !== '') {
setChips([...chips, inputValue.trim()]);
setInputValue(''); // Clear the input after adding the chip
const newChips = [...chips, inputValue.trim()];
setChips(newChips);
setInputValue('');

onChange(id, newChips);
}
};

// Function to remove chip
const handleDelete = (chipToDelete: any[]) => {
setChips(chips.filter((chip) => chip !== chipToDelete));
};

return (
<Box display="flex" alignItems="center" flexWrap="wrap" sx={{ gap: '8px', padding: '10px', borderRadius: 1, backgroundColor: '#ECECEC', mt: 1 }}>
<Box
display="flex"
alignItems="center"
flexWrap="wrap"
sx={[
(theme) => ({
gap: '8px',
padding: '10px',
borderRadius: 1,
backgroundColor: '#ECECEC',
mt: 1,
'&:focus-within': {
border: `2px solid ${theme.palette.primary.dark}`,
},
}),
]}
>
{chips.map((chip, index) => (
<Chip key={index} label={chip} onDelete={() => handleDelete(chip)} sx={{ backgroundColor: '#bfbfbf', color: '#000', fontSize: '14px' }} />
<Chip
key={index}
label={chip}
onDelete={() => handleDelete(chip)}
sx={[
(theme) => ({
backgroundColor: theme.palette.grey[100],
color: theme.palette.common.black,
fontSize: '14px',
}),
]}
/>
))}
<TextField
variant="standard"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Invite attendees"
InputProps={{
disableUnderline: true,
slotProps={{
input: {
disableUnderline: true,
},
}}
sx={{ flex: 1, py: 1, px: 1 }}
sx={[
(theme) => ({
flex: 1,
py: 1,
px: 1,
'& .MuiInputBase-input': {
fontSize: theme.typography.subtitle2,
},
'& .MuiInputBase-input::placeholder': {
color: theme.palette.primary,
fontSize: theme.typography.subtitle1,
},
}),
]}
/>
</Box>
);
Expand Down
10 changes: 10 additions & 0 deletions client/src/components/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import AccessTimeFilledRoundedIcon from '@mui/icons-material/AccessTimeFilledRou
import PeopleRoundedIcon from '@mui/icons-material/PeopleRounded';
import { convertToLocaleTime } from '../helpers/utility';
import { RoomResponse } from '../helpers/types';
import toast from 'react-hot-toast';

interface ChipData {
icon: React.ReactElement;
label: string;
color?: string;
type?: 'conference' | 'floor' | 'seats' | 'time' | 'room';
}

interface EventCardProps {
Expand Down Expand Up @@ -55,7 +57,9 @@ const EventCard = ({ sx, event, onDelete, disabled }: EventCardProps) => {
if (event?.conference) {
_chips.push({
label: event.conference,
type: 'conference',
icon: <InsertLinkRoundedIcon />,
color: '#99D2FF'
});
}

Expand Down Expand Up @@ -95,6 +99,12 @@ const EventCard = ({ sx, event, onDelete, disabled }: EventCardProps) => {
sx={{
fontSize: 14,
backgroundColor: chip.color,
cursor: chip.type === 'conference' ? 'pointer' : 'auto',
}}
onClick={() => {
if (chip.type === 'conference') {
window.open(`https://meet.google.com/${chip.label}`, '_blank');
}
}}
/>
</ListItem>
Expand Down
59 changes: 59 additions & 0 deletions client/src/components/StyledTextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Box, SxProps, TextField, Theme } from '@mui/material';

interface StyledTextFieldProps {
id: string;
sx?: SxProps<Theme>;
value?: string;
disabled?: boolean;
onChange: (id: string, value: string) => void;
}

const StyledTextField = ({ id, sx, disabled, onChange }: StyledTextFieldProps) => {
return (
<Box
display="flex"
alignItems="center"
flexWrap="wrap"
sx={[
(theme) => ({
gap: '8px',
padding: '10px',
borderRadius: 1,
backgroundColor: '#ECECEC',
mt: 1,
'&:focus-within': {
border: `2px solid ${theme.palette.primary.dark}`,
},
}),
]}
>
<TextField
onChange={(e) => onChange(id, e.target.value)}
variant="standard"
placeholder="Enter title"
slotProps={{
input: {
disableUnderline: true,
},
}}
fullWidth
sx={[
(theme) => ({
flex: 1,
py: 1,
px: 1,
'& .MuiInputBase-input': {
fontSize: theme.typography.subtitle1,
},
'& .MuiInputBase-input::placeholder': {
color: theme.palette.primary,
fontSize: theme.typography.subtitle1,
},
}),
]}
/>
</Box>
);
};

export default StyledTextField;
76 changes: 49 additions & 27 deletions client/src/pages/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {
Accordion,
AccordionDetails,
AccordionSummary,
BottomNavigation,
BottomNavigationAction,
Box,
Button,
Checkbox,
Chip,
Dialog,
DialogActions,
Expand All @@ -13,6 +17,7 @@ import {
Paper,
Stack,
styled,
TextField,
Typography,
} from '@mui/material';
import MuiCard from '@mui/material/Card';
Expand All @@ -39,6 +44,9 @@ import { CacheService, CacheServiceFactory } from '../../helpers/cache';
import { secrets } from '../../config/secrets';
import TopNavigationBar from './TopNavigationBar';
import { ROUTES } from '../../config/routes';
import ChipInput from '../../components/ChipInput';
import StyledTextField from '../../components/StyledTextField';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';

const isChromeExt = secrets.appEnvironment === 'chrome';
const roomChangeTimeFrame = 2;
Expand All @@ -57,6 +65,16 @@ interface Event {
createdAt?: number;
}

interface FormData {
startTime: string;
duration: number;
seats: number;
floor: string;
title?: string;
attendees?: string[];
conference?: boolean;
}

const CustomButton = styled(Button)(({ theme }) => ({
boxShadow: 'none',
'&:hover': {
Expand Down Expand Up @@ -126,7 +144,7 @@ const BookRoomView = () => {
const [requestedRoom, setRequestedRoom] = useState('');
const navigate = useNavigate();

const [formData, setFormData] = useState({
const [formData, setFormData] = useState<FormData>({
startTime: '',
duration: 15,
seats: 1,
Expand Down Expand Up @@ -174,11 +192,13 @@ const BookRoomView = () => {
});
}, []);

const handleInputChange = (id: string, value: string | number) => {
const handleInputChange = (id: string, value: string | number | string[] | boolean) => {
setFormData((prevData) => ({
...prevData,
[id]: value,
}));

console.log(formData);
};

const handleRoomChange = (id: string, value: string) => {
Expand Down Expand Up @@ -236,19 +256,20 @@ const BookRoomView = () => {

async function onBookClick() {
setLoading(true);
const { startTime, duration, floor, seats } = formData;
const { startTime, duration, floor, seats, conference, attendees, title } = formData;

const date = new Date(Date.now()).toISOString().split('T')[0];
const formattedStartTime = convertToRFC3339(date, startTime);

console.log('formattedStartTime', formattedStartTime);

const { data, redirect } = await makeRequest('/room', 'POST', {
startTime: formattedStartTime,
duration: duration,
seats: seats,
floor: floor,
timeZone: getTimeZoneString(),
createConference: conference,
title,
attendees,
});

if (redirect) {
Expand All @@ -260,6 +281,7 @@ const BookRoomView = () => {

if (data.error) {
toast.error(data.message);
setLoading(false);
return;
}

Expand Down Expand Up @@ -380,29 +402,29 @@ const BookRoomView = () => {
>
<Typography variant="h6">Book</Typography>
</LoadingButton>
{/* todo */}
{/* <Box mt={2}>
<Box display="flex" alignItems="center" flexWrap="wrap" sx={{ gap: '8px', padding: '10px', borderRadius: 1, backgroundColor: '#ECECEC', mt: 1 }}>
<TextField
variant="standard"
// value={inputValue}
// onChange={(e) => setInputValue(e.target.value)}
// onKeyDown={handleKeyDown}
placeholder="Enter title"
InputProps={{
disableUnderline: true,
}}
fullWidth
sx={{ flex: 1, py: 1, px: 1, fontWeight: 800, color: 'red' }}
/>
</Box>

<ChipInput />
<Box>
<Checkbox defaultChecked />
</Box>
</Box> */}
<Box sx={{ mt: 2, pb: 2 }}>
<Accordion
sx={{
boxShadow: '0 0px 6px 0 rgba(0,0,0,0.0), 0 3px 10px 0 rgba(0,0,0,0.2)',
}}
disableGutters
>
<AccordionSummary expandIcon={<ArrowDropDownIcon />} sx={{ px: 1.5 }} aria-controls="panel2-content" id="panel2-header">
<Typography>More options</Typography>
</AccordionSummary>
<AccordionDetails sx={{ py: 0, my: 0, px: 1.5 }}>
<Box pb={0}>
<StyledTextField id="title" onChange={handleInputChange} />
<ChipInput id="attendees" onChange={handleInputChange} />
<Box display={'flex'} mt={1} pb={1} alignItems={'center'}>
<Typography variant="subtitle2">Create online conference: </Typography>
<Checkbox onChange={(e) => handleInputChange('conference', e.target.checked)} />
</Box>
</Box>
</AccordionDetails>
</Accordion>
</Box>
</Box>

<Dialog
Expand Down
Loading

0 comments on commit 30bae01

Please sign in to comment.