Merge pull request #7 from Ryderjj89/dev
Updating frontend to have a copy link to RSVP and improvements to the…
This commit is contained in:
@@ -13,10 +13,13 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
Switch,
|
Switch,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
|
Snackbar,
|
||||||
|
Alert,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
|
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
|
||||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||||
import HowToRegIcon from '@mui/icons-material/HowToReg';
|
import HowToRegIcon from '@mui/icons-material/HowToReg';
|
||||||
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
interface Event {
|
interface Event {
|
||||||
@@ -33,6 +36,8 @@ const EventList: React.FC = () => {
|
|||||||
const [events, setEvents] = useState<Event[]>([]);
|
const [events, setEvents] = useState<Event[]>([]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [hideClosed, setHideClosed] = useState(false);
|
const [hideClosed, setHideClosed] = useState(false);
|
||||||
|
const [openSnackbar, setOpenSnackbar] = useState(false);
|
||||||
|
const [snackbarMessage, setSnackbarMessage] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchEvents();
|
fetchEvents();
|
||||||
@@ -63,6 +68,27 @@ const EventList: React.FC = () => {
|
|||||||
navigate(`/view/events/${event.slug}`);
|
navigate(`/view/events/${event.slug}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCopyLink = (event: Event) => {
|
||||||
|
const rsvpLink = `${window.location.origin}/rsvp/events/${event.slug}`;
|
||||||
|
navigator.clipboard.writeText(rsvpLink)
|
||||||
|
.then(() => {
|
||||||
|
setSnackbarMessage('RSVP link copied to clipboard!');
|
||||||
|
setOpenSnackbar(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
setSnackbarMessage('Failed to copy link.');
|
||||||
|
setOpenSnackbar(true);
|
||||||
|
console.error('Failed to copy: ', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseSnackbar = (event?: React.SyntheticEvent | Event, reason?: string) => {
|
||||||
|
if (reason === 'clickaway') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setOpenSnackbar(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Container maxWidth="md" sx={{ textAlign: 'center', mb: 8 }}>
|
<Container maxWidth="md" sx={{ textAlign: 'center', mb: 8 }}>
|
||||||
@@ -92,7 +118,7 @@ const EventList: React.FC = () => {
|
|||||||
control={
|
control={
|
||||||
<Switch
|
<Switch
|
||||||
checked={hideClosed}
|
checked={hideClosed}
|
||||||
onChange={(_, checked) => setHideClosed(checked)}
|
onChange={(event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => setHideClosed(checked)}
|
||||||
color="primary"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -106,7 +132,7 @@ const EventList: React.FC = () => {
|
|||||||
{events
|
{events
|
||||||
.filter(event => !hideClosed || isEventOpen(event))
|
.filter(event => !hideClosed || isEventOpen(event))
|
||||||
.map((event) => (
|
.map((event) => (
|
||||||
<Grid item xs={12} sm={6} md={6} key={event.id}>
|
<Grid item xs={12} sm={6} md={12} key={event.id}>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
height: '100%',
|
height: '100%',
|
||||||
@@ -172,12 +198,24 @@ const EventList: React.FC = () => {
|
|||||||
>
|
>
|
||||||
Manage
|
Manage
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
startIcon={<ContentCopyIcon />}
|
||||||
|
onClick={() => handleCopyLink(event)}
|
||||||
|
>
|
||||||
|
Copy RSVP Link
|
||||||
|
</Button>
|
||||||
</CardActions>
|
</CardActions>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
|
<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar}>
|
||||||
|
<Alert onClose={handleCloseSnackbar} severity="success" sx={{ width: '100%' }}>
|
||||||
|
{snackbarMessage}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const RSVPForm: React.FC = () => {
|
|||||||
const [success, setSuccess] = useState(false);
|
const [success, setSuccess] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [event, setEvent] = useState<Event | null>(null);
|
const [event, setEvent] = useState<Event | null>(null);
|
||||||
|
const [isItemsSelectOpen, setIsItemsSelectOpen] = useState(false); // State to control select dropdown
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchEventDetails = async () => {
|
const fetchEventDetails = async () => {
|
||||||
@@ -590,6 +591,22 @@ const RSVPForm: React.FC = () => {
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
open={isItemsSelectOpen} // Control open state
|
||||||
|
onOpen={() => setIsItemsSelectOpen(true)} // Set open when opened
|
||||||
|
onClose={() => setIsItemsSelectOpen(false)} // Set closed when closed
|
||||||
|
MenuProps={{
|
||||||
|
PaperProps: {
|
||||||
|
sx: {
|
||||||
|
maxHeight: 300, // Limit height of the dropdown
|
||||||
|
overflowY: 'auto',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MenuListProps: {
|
||||||
|
sx: {
|
||||||
|
paddingBottom: '60px', // Make space for the button
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{neededItems.map((item) => (
|
{neededItems.map((item) => (
|
||||||
<MenuItem key={item} value={item}>
|
<MenuItem key={item} value={item}>
|
||||||
@@ -597,6 +614,26 @@ const RSVPForm: React.FC = () => {
|
|||||||
<ListItemText primary={item} />
|
<ListItemText primary={item} />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
|
<Box sx={{
|
||||||
|
position: 'sticky',
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: 'background.paper',
|
||||||
|
padding: 1,
|
||||||
|
zIndex: 1,
|
||||||
|
borderTop: '1px solid',
|
||||||
|
borderColor: 'divider',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => setIsItemsSelectOpen(false)}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
Done
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user