Fix claimed items state management and wallpaper display
This commit is contained in:
@@ -16,6 +16,17 @@ import {
|
|||||||
Chip
|
Chip
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
|
interface Event {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
date: string;
|
||||||
|
location: string;
|
||||||
|
slug: string;
|
||||||
|
needed_items?: string[] | string;
|
||||||
|
wallpaper?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const EventDetails: React.FC = () => {
|
const EventDetails: React.FC = () => {
|
||||||
const { slug } = useParams<{ slug: string }>();
|
const { slug } = useParams<{ slug: string }>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -66,7 +77,7 @@ const EventDetails: React.FC = () => {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundImage: 'url(https://www.rydertech.us/backgrounds/space1.jpg)',
|
backgroundImage: event?.wallpaper ? `url(${event.wallpaper})` : 'url(https://www.rydertech.us/backgrounds/space1.jpg)',
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
}}
|
}}
|
||||||
@@ -93,118 +104,128 @@ const EventDetails: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container maxWidth="md">
|
<Box
|
||||||
<Paper sx={{ p: 4, mb: 4 }}>
|
sx={{
|
||||||
<Typography variant="h4" component="h1" gutterBottom>
|
minHeight: '100vh',
|
||||||
{event.title}
|
backgroundImage: event.wallpaper ? `url(${event.wallpaper})` : 'url(https://www.rydertech.us/backgrounds/space1.jpg)',
|
||||||
</Typography>
|
backgroundSize: 'cover',
|
||||||
<Typography variant="body1" paragraph>
|
backgroundPosition: 'center',
|
||||||
{event.description}
|
py: 4,
|
||||||
</Typography>
|
}}
|
||||||
<Box sx={{ mb: 3 }}>
|
>
|
||||||
<Typography variant="subtitle1" component="div" gutterBottom>
|
<Container maxWidth="md">
|
||||||
<strong>Date:</strong> {new Date(event.date).toLocaleDateString()}
|
<Paper sx={{ p: 4, mb: 4, backgroundColor: 'rgba(255, 255, 255, 0.95)' }}>
|
||||||
|
<Typography variant="h4" component="h1" gutterBottom>
|
||||||
|
{event.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="subtitle1" component="div">
|
<Typography variant="body1" paragraph>
|
||||||
<strong>Location:</strong> {event.location}
|
{event.description}
|
||||||
</Typography>
|
</Typography>
|
||||||
{event.needed_items && event.needed_items.length > 0 && (
|
<Box sx={{ mb: 3 }}>
|
||||||
<Box sx={{ mt: 2 }}>
|
<Typography variant="subtitle1" component="div" gutterBottom>
|
||||||
<Typography variant="subtitle1" component="div" gutterBottom>
|
<strong>Date:</strong> {new Date(event.date).toLocaleDateString()}
|
||||||
<strong>Needed Items:</strong>
|
</Typography>
|
||||||
</Typography>
|
<Typography variant="subtitle1" component="div">
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
<strong>Location:</strong> {event.location}
|
||||||
{event.needed_items.map((item, index) => (
|
</Typography>
|
||||||
<Chip key={index} label={item} color="primary" />
|
{event.needed_items && event.needed_items.length > 0 && (
|
||||||
))}
|
<Box sx={{ mt: 2 }}>
|
||||||
|
<Typography variant="subtitle1" component="div" gutterBottom>
|
||||||
|
<strong>Needed Items:</strong>
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
||||||
|
{event.needed_items.map((item, index) => (
|
||||||
|
<Chip key={index} label={item} color="primary" />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
)}
|
</Box>
|
||||||
</Box>
|
<Button
|
||||||
<Button
|
variant="contained"
|
||||||
variant="contained"
|
color="primary"
|
||||||
color="primary"
|
onClick={() => navigate(`/events/${event.slug}/rsvp`)}
|
||||||
onClick={() => navigate(`/events/${event.slug}/rsvp`)}
|
>
|
||||||
>
|
RSVP to Event
|
||||||
RSVP to Event
|
</Button>
|
||||||
</Button>
|
</Paper>
|
||||||
</Paper>
|
|
||||||
|
|
||||||
<Paper sx={{ p: 4 }}>
|
<Paper sx={{ p: 4 }}>
|
||||||
<Typography
|
<Typography
|
||||||
variant="h5"
|
variant="h5"
|
||||||
gutterBottom
|
gutterBottom
|
||||||
sx={{
|
sx={{
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
color: 'primary.main',
|
color: 'primary.main',
|
||||||
mb: 2,
|
mb: 2,
|
||||||
borderBottom: '2px solid',
|
borderBottom: '2px solid',
|
||||||
borderColor: 'primary.main',
|
borderColor: 'primary.main',
|
||||||
pb: 1
|
pb: 1
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
RSVPs
|
RSVPs
|
||||||
</Typography>
|
</Typography>
|
||||||
<List sx={{
|
<List sx={{
|
||||||
bgcolor: 'rgba(255, 255, 255, 0.1)',
|
bgcolor: 'rgba(255, 255, 255, 0.1)',
|
||||||
borderRadius: 1,
|
borderRadius: 1,
|
||||||
boxShadow: '0 2px 4px rgba(0,0,0,0.05)'
|
boxShadow: '0 2px 4px rgba(0,0,0,0.05)'
|
||||||
}}>
|
}}>
|
||||||
{rsvps.map((rsvp) => (
|
{rsvps.map((rsvp) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
key={rsvp.id}
|
key={rsvp.id}
|
||||||
sx={{
|
sx={{
|
||||||
borderBottom: '1px solid',
|
borderBottom: '1px solid',
|
||||||
borderColor: 'divider',
|
borderColor: 'divider',
|
||||||
'&:last-child': {
|
'&:last-child': {
|
||||||
borderBottom: 'none'
|
borderBottom: 'none'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
<Typography variant="subtitle1" sx={{ fontWeight: 500 }}>
|
<Typography variant="subtitle1" sx={{ fontWeight: 500 }}>
|
||||||
{rsvp.name}
|
{rsvp.name}
|
||||||
|
</Typography>
|
||||||
|
<Chip
|
||||||
|
label={formatAttendingStatus(rsvp.attending)}
|
||||||
|
color={getStatusColor(rsvp.attending)}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
secondary={
|
||||||
|
<Box sx={{ mt: 1 }}>
|
||||||
|
{rsvp.bringing_guests === 'yes' && (
|
||||||
|
<Typography variant="body2" color="text.secondary" paragraph>
|
||||||
|
Bringing {rsvp.guest_count} guest{rsvp.guest_count !== 1 ? 's' : ''}: {rsvp.guest_names}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{rsvp.items_bringing && rsvp.items_bringing.length > 0 && (
|
||||||
|
<Typography>
|
||||||
|
<strong>Items:</strong> {Array.isArray(rsvp.items_bringing) ? rsvp.items_bringing.join(', ') : rsvp.items_bringing}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
{rsvps.length === 0 && (
|
||||||
|
<ListItem>
|
||||||
|
<ListItemText
|
||||||
|
primary={
|
||||||
|
<Typography variant="body1" color="text.secondary" align="center">
|
||||||
|
No RSVPs yet
|
||||||
</Typography>
|
</Typography>
|
||||||
<Chip
|
}
|
||||||
label={formatAttendingStatus(rsvp.attending)}
|
/>
|
||||||
color={getStatusColor(rsvp.attending)}
|
</ListItem>
|
||||||
size="small"
|
)}
|
||||||
/>
|
</List>
|
||||||
</Box>
|
</Paper>
|
||||||
}
|
</Container>
|
||||||
secondary={
|
</Box>
|
||||||
<Box sx={{ mt: 1 }}>
|
|
||||||
{rsvp.bringing_guests === 'yes' && (
|
|
||||||
<Typography variant="body2" color="text.secondary" paragraph>
|
|
||||||
Bringing {rsvp.guest_count} guest{rsvp.guest_count !== 1 ? 's' : ''}: {rsvp.guest_names}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
{rsvp.items_bringing && rsvp.items_bringing.length > 0 && (
|
|
||||||
<Typography>
|
|
||||||
<strong>Items:</strong> {Array.isArray(rsvp.items_bringing) ? rsvp.items_bringing.join(', ') : rsvp.items_bringing}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
))}
|
|
||||||
{rsvps.length === 0 && (
|
|
||||||
<ListItem>
|
|
||||||
<ListItemText
|
|
||||||
primary={
|
|
||||||
<Typography variant="body1" color="text.secondary" align="center">
|
|
||||||
No RSVPs yet
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
</List>
|
|
||||||
</Paper>
|
|
||||||
</Container>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -90,9 +90,8 @@ const EventView: React.FC = () => {
|
|||||||
itemsBringing = rsvp.items_bringing;
|
itemsBringing = rsvp.items_bringing;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemsBringing.length > 0) {
|
// Add items to claimed set
|
||||||
itemsBringing.forEach(item => claimed.add(item));
|
itemsBringing.forEach(item => claimed.add(item));
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error processing items for RSVP:', e);
|
console.error('Error processing items for RSVP:', e);
|
||||||
}
|
}
|
||||||
@@ -103,12 +102,11 @@ const EventView: React.FC = () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter out claimed items from needed items
|
// Update state with processed data
|
||||||
const availableItems = items.filter(item => !claimed.has(item));
|
|
||||||
|
|
||||||
setNeededItems(availableItems);
|
|
||||||
setClaimedItems(Array.from(claimed));
|
|
||||||
setRsvps(processedRsvps);
|
setRsvps(processedRsvps);
|
||||||
|
setClaimedItems(Array.from(claimed));
|
||||||
|
// Filter needed items to only show unclaimed ones
|
||||||
|
setNeededItems(items.filter(item => !claimed.has(item)));
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError('Failed to load event data');
|
setError('Failed to load event data');
|
||||||
|
|||||||
Reference in New Issue
Block a user