diff --git a/frontend/components/group/Invitation.tsx b/frontend/components/group/Invitation.tsx new file mode 100644 index 00000000..9859e59b --- /dev/null +++ b/frontend/components/group/Invitation.tsx @@ -0,0 +1,62 @@ +import { Trans } from "@lingui/macro"; +import clsx from "clsx"; +import Link from "next/link"; +import { Check, X } from "react-feather"; + +import { Button } from "@/components/input/Button"; +import { Invitation as InvitationType } from "@/types/Invitation"; +import { declineGroupInvitation, sendGroupRequest } from "@/util/api"; + +import { Text } from "../Text"; + +interface InvitationProps { + /** + * Invitation + */ + invitation: InvitationType; + /** + * Additional classes + */ + className?: string; +} + +/** + * Component for displaying a group invitation in the notification center + */ +export const Invitation = ({ invitation, className }: InvitationProps) => { + return ( +
+
+
+ + Group Invitation + + + + You have been invited to join{" "} + + {invitation.groupName} + + + +
+
+
+
+ ); +}; diff --git a/frontend/components/input/Button.tsx b/frontend/components/input/Button.tsx index 4be8a283..44ad9592 100644 --- a/frontend/components/input/Button.tsx +++ b/frontend/components/input/Button.tsx @@ -37,7 +37,7 @@ const getStyle = { secondary: "bg-black font-medium text-white hover:scale-[1.02] hover:bg-neutral-900", tertiary: - "bg-transparent font-medium text-kiokuDarkBlue hover:scale-105 hover:bg-gray-100", + "bg-transparent font-medium text-black hover:scale-105 hover:bg-gray-100", cancel: "bg-transparent font-normal text-gray-400 hover:bg-gray-100", error: "bg-kiokuRed font-medium text-white hover:scale-105", warning: "bg-kiokuYellow font-medium text-white hover:scale-105", @@ -78,12 +78,15 @@ export const Button = ({ ); const classNames = [ - "flex items-center space-x-1 rounded-md outline-none transition", + "flex items-center rounded-md outline-none transition", className, ]; if (buttonStyle) { classNames.push(getStyle[buttonStyle]); } + if (buttonIcon && children) { + classNames.push("space-x-1"); + } classNames.push(buttonSize); return href ? ( diff --git a/frontend/components/modal/NotificationCenter.tsx b/frontend/components/modal/NotificationCenter.tsx new file mode 100644 index 00000000..b34fe0c5 --- /dev/null +++ b/frontend/components/modal/NotificationCenter.tsx @@ -0,0 +1,68 @@ +import { Trans } from "@lingui/macro"; +import { useState } from "react"; +import { Bell, Info } from "react-feather"; + +import { Invitation } from "@/components/group/Invitation"; +import { Modal, ModalProps } from "@/components/modal/modal"; +import { useInvitations } from "@/util/swr"; + +/** + * Component for displaying an icon that opens the notification center + */ +export const NotificationCenter = () => { + const { invitations } = useInvitations(); + + const [showNotificationCenter, setShowNotificationCenter] = + useState(false); + + return ( + <> + +
+ { + setShowNotificationCenter(true); + }} + /> + {invitations && ( +
+
+
+ )} +
+ + ); +}; + +/** + * Modal for creating decks + */ +export const NotificationCenterModal = ({ + className = "", + setVisible, + ...props +}: ModalProps) => { + const { invitations } = useInvitations(); + + return ( + + {invitations ? ( + invitations.map((invitation) => ( + + )) + ) : ( +
+ + You have no pending messages +
+ )} +
+ ); +}; diff --git a/frontend/components/modal/modal.tsx b/frontend/components/modal/modal.tsx index 64faa12a..0a0449f7 100644 --- a/frontend/components/modal/modal.tsx +++ b/frontend/components/modal/modal.tsx @@ -53,7 +53,7 @@ export const Modal = ({
{header} diff --git a/frontend/components/navigation/Navbar.tsx b/frontend/components/navigation/Navbar.tsx index e433698a..f45aba36 100644 --- a/frontend/components/navigation/Navbar.tsx +++ b/frontend/components/navigation/Navbar.tsx @@ -6,8 +6,9 @@ import { ArrowRight, LogOut } from "react-feather"; import { Logo } from "@/components/graphics/Logo"; import { Button } from "@/components/input/Button"; +import { NotificationCenter } from "@/components/modal/NotificationCenter"; +import { postRequest } from "@/util/api"; import { logoutRoute } from "@/util/endpoints"; -import { authedFetch } from "@/util/reauth"; interface NavbarProps { /** @@ -21,7 +22,9 @@ interface NavbarProps { */ export const Navbar = ({ className = "" }: NavbarProps) => { const router = useRouter(); + const [loggedIn, setLoggedIn] = useState(); + useEffect(() => { if (router.pathname == "/login") { setLoggedIn(undefined); @@ -29,26 +32,29 @@ export const Navbar = ({ className = "" }: NavbarProps) => { setLoggedIn(hasCookie("access_token")); } }, [router.pathname]); + if (loggedIn == undefined) { return <>; } + return (