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:
Joshua Ryder
2025-06-04 17:16:47 -04:00
committed by GitHub
2 changed files with 78 additions and 3 deletions

View File

@@ -13,10 +13,13 @@ import {
Stack,
Switch,
FormControlLabel,
Snackbar,
Alert,
} from '@mui/material';
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
import VisibilityIcon from '@mui/icons-material/Visibility';
import HowToRegIcon from '@mui/icons-material/HowToReg';
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import axios from 'axios';
interface Event {
@@ -33,6 +36,8 @@ const EventList: React.FC = () => {
const [events, setEvents] = useState<Event[]>([]);
const navigate = useNavigate();
const [hideClosed, setHideClosed] = useState(false);
const [openSnackbar, setOpenSnackbar] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
useEffect(() => {
fetchEvents();
@@ -63,6 +68,27 @@ const EventList: React.FC = () => {
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 (
<Box>
<Container maxWidth="md" sx={{ textAlign: 'center', mb: 8 }}>
@@ -92,7 +118,7 @@ const EventList: React.FC = () => {
control={
<Switch
checked={hideClosed}
onChange={(_, checked) => setHideClosed(checked)}
onChange={(event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => setHideClosed(checked)}
color="primary"
/>
}
@@ -106,7 +132,7 @@ const EventList: React.FC = () => {
{events
.filter(event => !hideClosed || isEventOpen(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
sx={{
height: '100%',
@@ -172,14 +198,26 @@ const EventList: React.FC = () => {
>
Manage
</Button>
<Button
size="small"
startIcon={<ContentCopyIcon />}
onClick={() => handleCopyLink(event)}
>
Copy RSVP Link
</Button>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar}>
<Alert onClose={handleCloseSnackbar} severity="success" sx={{ width: '100%' }}>
{snackbarMessage}
</Alert>
</Snackbar>
</Box>
);
};
export default EventList;
export default EventList;

View File

@@ -52,6 +52,7 @@ const RSVPForm: React.FC = () => {
const [success, setSuccess] = useState(false);
const navigate = useNavigate();
const [event, setEvent] = useState<Event | null>(null);
const [isItemsSelectOpen, setIsItemsSelectOpen] = useState(false); // State to control select dropdown
useEffect(() => {
const fetchEventDetails = async () => {
@@ -590,6 +591,22 @@ const RSVPForm: React.FC = () => {
))}
</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) => (
<MenuItem key={item} value={item}>
@@ -597,6 +614,26 @@ const RSVPForm: React.FC = () => {
<ListItemText primary={item} />
</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>
</FormControl>
)}