-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: made new database table for roombookings
- Loading branch information
1 parent
fcb7d4c
commit a04dd9a
Showing
13 changed files
with
515 additions
and
140 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { useEffect, useState } from "react"; | ||
import { periodType, RoomBooking } from "../../lib/types/types"; | ||
import Button from "../Button"; | ||
import Table, { ColumnType } from "../Table"; | ||
import DateInput from "../form/DateInput"; | ||
import TextInput from "../form/TextInput"; | ||
import TimeRangeInput from "../form/TimeRangeInput"; | ||
|
||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; | ||
import { WithId } from "mongodb"; | ||
import toast from "react-hot-toast"; | ||
import { createRoom, deleteRoom, fetchRoomsByPeriodId } from "../../lib/api/roomApi"; | ||
|
||
interface Props { | ||
period?: periodType; | ||
} | ||
|
||
const RoomInterview = ({ | ||
period | ||
}: Props) => { | ||
|
||
const queryClient = useQueryClient(); | ||
|
||
// TODO: Fix correct tabbing | ||
const [roomBookings, setRoomBookings] = useState<WithId<RoomBooking>[]>([]) | ||
|
||
const [date, setDate] = useState<string>(""); | ||
const [startTime, setStartTime] = useState<string>(""); | ||
const [endTime, setEndTime] = useState<string>(""); | ||
const [room, setRoom] = useState<string>(""); | ||
|
||
const isValidBooking = () => { | ||
if (!room) { | ||
toast.error("Vennligst fyll inn rom") | ||
return false; | ||
} | ||
if (!date) { | ||
toast.error("Vennligst velg dato") | ||
return false; | ||
} | ||
if (!startTime || !endTime) { | ||
toast.error("Vennligst velg tidspunkt") | ||
return false; | ||
} | ||
if (Date.parse("2003-07-26T" + startTime) - Date.parse("2003-07-26T" + endTime) > 0) { | ||
toast.error("Starttid må være før sluttid") | ||
return false; | ||
} | ||
|
||
// TODO: Make sure time is within interviewPeriod | ||
|
||
return true; | ||
} | ||
|
||
const { | ||
data: roomData, | ||
} = useQuery({ | ||
queryKey: ["rooms", period?._id], | ||
queryFn: fetchRoomsByPeriodId | ||
}) | ||
|
||
const createRoomBookingMutation = useMutation({ | ||
mutationFn: createRoom, | ||
onSuccess: () => | ||
queryClient.invalidateQueries({ | ||
// TODO: try to update cache instead | ||
queryKey: ["rooms", period?._id], | ||
}), | ||
}); | ||
|
||
const deleteRoomBookingMutation = useMutation({ | ||
mutationFn: (roomId: string) => deleteRoom(roomId, String(period!._id)), | ||
onSuccess: () => | ||
queryClient.invalidateQueries({ | ||
// TODO: try to update cache instead | ||
queryKey: ["rooms", period?._id], | ||
}), | ||
}); | ||
|
||
useEffect(() => { | ||
if (!roomData) return | ||
const { rooms } = roomData | ||
console.log(rooms) | ||
setRoomBookings(rooms) | ||
}, [roomData]) | ||
|
||
const handleAddBooking = () => { | ||
if (!isValidBooking()) return; | ||
addBooking() | ||
setRoom("") | ||
} | ||
|
||
const addBooking = () => { | ||
const booking: RoomBooking = { | ||
periodId: String(period?._id), | ||
room: room, | ||
startDate: new Date(date.split("T")[0] + "T" + startTime), | ||
endDate: new Date(date.split("T")[0] + "T" + endTime) | ||
} | ||
|
||
createRoomBookingMutation.mutate(booking) | ||
} | ||
|
||
const handleDeleteBooking = async (booking: WithId<RoomBooking>) => { | ||
if (!period) return; | ||
const isConfirmed = window.confirm( | ||
`Er det sikker på at du ønsker å fjerne bookingen av ${booking.room} fra ${booking.startDate} til ${booking.endDate}?` | ||
); | ||
if (!isConfirmed) return; | ||
|
||
setRoomBookings(roomBookings.filter((bookingA) => bookingA._id != booking._id)) | ||
|
||
deleteRoomBookingMutation.mutate(String(booking._id)) | ||
}; | ||
|
||
const columns: ColumnType[] = [ | ||
{ label: "Rom", field: "room" }, | ||
{ label: "Dato", field: "date" }, | ||
{ label: "Fra", field: "from" }, | ||
{ label: "Til", field: "to" }, | ||
{ label: "Slett", field: "delete" }, | ||
] | ||
|
||
return <div className="flex flex-col items-center"> | ||
<h2 className="px-5 mt-5 mb-6 text-2xl font-semibold text-center">Legg inn romvalg</h2> | ||
<div className="mb-5 flex flex-col justify-center"> | ||
<div className="flex flex-row justify-center gap-10 items-baseline w-full"> | ||
<TextInput | ||
defaultValue={room} | ||
updateInputValues={(input: string) => { | ||
setRoom(input) | ||
}} | ||
label="Romnavn" | ||
className="mx-0" | ||
/> | ||
<DateInput | ||
updateDate={(date: string) => { | ||
setDate(date) | ||
}} | ||
label="Test" | ||
/> | ||
<TimeRangeInput | ||
updateTimes={(times: { start: string, end: string }) => { | ||
setStartTime(times.start) | ||
setEndTime(times.end) | ||
}} | ||
className="mx-0" | ||
/> | ||
</div> | ||
<Button title="Legg til" color="blue" onClick={handleAddBooking}></Button> | ||
</div> | ||
<h2 className="px-5 mt-5 mb-6 text-2xl font-semibold text-center">Alle tilgjengelige romvalg</h2> | ||
{roomBookings?.length ? <Table columns={columns} rows={roomBookings.map((roomBooking) => { | ||
return { | ||
id: String(roomBooking._id), | ||
room: roomBooking.room, | ||
date: new Date(roomBooking.startDate).toLocaleDateString(), | ||
from: new Date(roomBooking.startDate).toLocaleTimeString(), | ||
to: new Date(roomBooking.endDate).toLocaleTimeString() | ||
} | ||
})} onDelete={(id: string, name: string) => { | ||
const deletedBooking = roomBookings.find((booking, index, array) => { | ||
return String(booking._id) == id | ||
}) | ||
handleDeleteBooking(deletedBooking!) | ||
}} /> | ||
: <p><i>Legg inn et rom, så dukker det opp her.</i></p>} | ||
</div> | ||
}; | ||
|
||
export default RoomInterview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { QueryFunctionContext } from "@tanstack/react-query"; | ||
import { RoomBooking } from "../types/types"; | ||
|
||
export const fetchRoomByPeriodAndId = async (context: QueryFunctionContext) => { | ||
const periodId = context.queryKey[1]; | ||
const roomId = context.queryKey[2]; | ||
return fetch(`/api/rooms/${periodId}/${roomId}`).then((res) => res.json()); | ||
}; | ||
|
||
export const fetchRoomsByPeriodId = async (context: QueryFunctionContext) => { | ||
const periodId = context.queryKey[1]; | ||
return fetch(`/api/rooms/${periodId}`).then((res) => res.json()); | ||
}; | ||
|
||
export const createRoom = async (room: RoomBooking): Promise<RoomBooking> => { | ||
const response = await fetch(`/api/rooms/`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify(room), | ||
}); | ||
|
||
const { message, data, error } = await response.json(); | ||
if (!response.ok) { | ||
throw new Error(error || "Unknown error occurred"); | ||
} | ||
return data; | ||
}; | ||
|
||
export const deleteRoom = async (roomId: string, periodId: string) => { | ||
const response = await fetch(`/api/rooms/${periodId}/${roomId}`, { | ||
method: "DELETE", | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error("Failed to delete the room"); | ||
} | ||
|
||
return response; | ||
}; |
Oops, something went wrong.