Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nsc-events-nextjs-256-archive-functionality #257

Merged
merged 8 commits into from
Apr 23, 2024
Merged
10 changes: 9 additions & 1 deletion app/event-detail/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogActions from "@mui/material/DialogActions";
import { useRouter } from "next/navigation";
import ArchiveDialog from "@/components/ArchiveDialog";


interface SearchParams {
Expand All @@ -31,6 +32,7 @@ const EventDetail = ({ searchParams }: SearchParams) => {
const [isAuthed, setAuthed] = useState(false);
const [token, setToken] = useState("")
const [dialogOpen, setDialogOpen] = useState(false);
const [archiveDialogOpen, setArchiveDialogOpen] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState("")
const queryClient = useQueryClient();

Expand Down Expand Up @@ -120,6 +122,11 @@ const EventDetail = ({ searchParams }: SearchParams) => {
}, [queryClient, searchParams.id]

)

const toggleArchiveDialog = () => {
setArchiveDialogOpen(!archiveDialogOpen);
}

return (
<>
<Box className={styles.container}>
Expand Down Expand Up @@ -159,14 +166,15 @@ const EventDetail = ({ searchParams }: SearchParams) => {
<>
<Button variant='contained' sx={{ color:'white', backgroundColor: '#2074d4', width: '125px' }}> <EditIcon sx={ { marginRight: '5px' }}/> Edit </Button>
<Button variant='contained' sx={{ color:'white', backgroundColor: '#2074d4', width: '125px' }} onClick={ () => setDialogOpen(true)} > <DeleteIcon sx={ { marginRight: '5px' }}/> Delete </Button>
<Button variant='contained' sx={{ color:'white', backgroundColor: '#2074d4', width: '125px' }}> <ArchiveIcon sx={ { marginRight: '5px' }}/> Archive </Button>
<Button variant='contained' sx={{ color:'white', backgroundColor: '#2074d4', width: '125px' }} onClick={ () => toggleArchiveDialog() }> <ArchiveIcon sx={ { marginRight: '5px' }}/> Archive </Button>
</>)
}
</div>
<Button variant='contained' sx={{ color:'white', backgroundColor: '#2074d4', width: '125px', marginRight: '50px' }}> Attend </Button>
</div>
</Box>
<DeleteDialog/>
<ArchiveDialog isOpen={archiveDialogOpen} eventId={event._id} dialogToggle={toggleArchiveDialog}/>
<Snackbar
open={Boolean(snackbarMessage)}
onClose={() => {
Expand Down
93 changes: 93 additions & 0 deletions components/ArchiveDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Dialog from "@mui/material/Dialog";
import DialogTitle from "@mui/material/DialogTitle";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogActions from "@mui/material/DialogActions";
import { Button } from "@mui/material";
import React, { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import Snackbar from "@mui/material/Snackbar";

interface ArchiveDialogProps {
isOpen: boolean;
eventId: string;
dialogToggle: () => void;
}

const ArchiveDialog = ({ isOpen, eventId, dialogToggle }: ArchiveDialogProps) => {
const router = useRouter();
const [snackbarMessage, setSnackbarMessage] = useState("")

const archiveEvent = async (id: string) => {
const token = localStorage.getItem("token");
try {
const response = await fetch(`http://localhost:3000/api/events/archive/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
return response.json();
} catch (error) {
console.error('error: ', error)
}
}

const { mutate: archiveEventMutation } = useMutation({
mutationFn: archiveEvent,
onSuccess: () => {
setSnackbarMessage("Successfully archived event.");
setTimeout( () => {
router.push("/");
}, 1200);

},
onError: (error: String) => {
setSnackbarMessage("Failed to archive event.");
console.error("Failed to archive event: ", error)
}
})

const handleClick = () => {
dialogToggle();
}

return (
<>
<Dialog
open={isOpen}>
<DialogTitle>
{"Archive Event?"}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Are you sure you want to archive this event?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={ () => {
handleClick()
} }>Cancel</Button>
<Button onClick={() => {
archiveEventMutation(eventId)
handleClick()
}} autoFocus>
Archive
</Button>
</DialogActions>
</Dialog>
<Snackbar
open={Boolean(snackbarMessage)}
onClose={() => {
setSnackbarMessage("")
}}
autoHideDuration={1200}
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
message={snackbarMessage}
/>
</>
)
}
export default ArchiveDialog;
14 changes: 9 additions & 5 deletions components/HomeEventGetter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ const getEvents = async() => {
return response.json();
}


export function HomeEventsList(){

const { data, isLoading, isError } = useQuery<ActivityDatabase[]>({
export function useFilteredEvents() {
return useQuery({
queryKey: ["event"],
queryFn: getEvents,
select: (data) => data.sort((event1, event2) => {
select: (data: ActivityDatabase[]) => data.filter( event =>
!(event.isHidden) && !(event.isArchived))?.sort((event1, event2) => {
return new Date(event1.eventDate).getTime() - new Date(event2.eventDate).getTime();
}),
});
}

export function HomeEventsList(){

const { data, isLoading, isError } = useFilteredEvents();

if(isLoading) {
return <span>Loading events...</span>
Expand Down
16 changes: 2 additions & 14 deletions components/UpcomingEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
'use client';

import React from "react";
import { useQuery } from "@tanstack/react-query";
import { Card, CardContent, CardMedia, Typography, Grid, Box, CardActions, Button } from '@mui/material';
import Link from "next/link";
import { ActivityDatabase } from "@/models/activityDatabase";

const getEvents = async() => {
const response = await fetch("http://localhost:3000/api/events");
return response.json();
}

import { useFilteredEvents } from "@/components/HomeEventGetter";
export function UpcomingEvent(){

const { data, isLoading, isError } = useQuery<ActivityDatabase[]>({
queryKey: ["event"],
queryFn: getEvents,
select: (data: ActivityDatabase[]) => {
return data.filter( (event) => event.isHidden?.valueOf() === false)
},
});
const { data, isLoading, isError } = useFilteredEvents();

if(isLoading) {
return <span>Loading events...</span>
Expand Down
1 change: 1 addition & 0 deletions models/activityDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface ActivityDatabase {
eventPrivacy: string;
eventAccessibility: string;
isHidden?: boolean;
isArchived?: boolean;
}

export const activityDatabase: ActivityDatabase = {
Expand Down
Loading