Skip to content

Commit

Permalink
Merge pull request #39 from game-node-app/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Lamarcke authored Mar 19, 2024
2 parents 39e9831 + 1eaa896 commit dd722d1
Show file tree
Hide file tree
Showing 21 changed files with 508 additions and 131 deletions.
1 change: 1 addition & 0 deletions .idea/game-node-web.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ services:
NEXT_PUBLIC_SEARCH_URL: ${NEXT_PUBLIC_SEARCH_URL}

networks:
- game_node_app
- game_node_app_public


networks:
game_node_app:
game_node_app_public:
external: true

volumes:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@mantine/notifications": "^7.1.3",
"@mantine/nprogress": "^7.1.3",
"@mantine/tiptap": "^7.2.1",
"@socialgouv/matomo-next": "^1.8.1",
"@tabler/icons-react": "^2.40.0",
"@tanstack/react-query": "^5.8.7",
"@tiptap/extension-link": "^2.1.12",
Expand Down
11 changes: 11 additions & 0 deletions src/components/auth/SuperTokensProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ export const frontendConfig = () => {
ThirdPartyPasswordlessReact.Discord.init(),
],
},
onHandleEvent: (context) => {
// Sends user to /wizard/init on sign-up
if (context.action === "SUCCESS") {
if (
context.isNewRecipeUser &&
context.user.loginMethods.length === 1
) {
Router.push("/wizard/init");
}
}
},
}),
SessionReact.init(),
],
Expand Down
70 changes: 70 additions & 0 deletions src/components/general/MatomoTracker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useCallback, useEffect } from "react";
import { init } from "@socialgouv/matomo-next";
import { useLocalStorage, useSessionStorage } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { Button, Flex, Group, Stack, Text } from "@mantine/core";
import Link from "next/link";

const MATOMO_URL = process.env.NEXT_PUBLIC_MATOMO_URL;
const MATOMO_SITE_ID = process.env.NEXT_PUBLIC_MATOMO_SITE_ID;

const MatomoTracker = () => {
const [hasAcceptedCookies, setHasAcceptedCookies] =
useLocalStorage<boolean>({
key: "cookie-consent",
defaultValue: false,
getInitialValueInEffect: false,
});

console.log(hasAcceptedCookies);

const showCookieConsentNotification = useCallback(() => {
if (hasAcceptedCookies != undefined && hasAcceptedCookies) return;
notifications.show({
id: "cookie-notice",
title: "Notice",
withCloseButton: false,
autoClose: false,
withBorder: true,
message: (
<Stack className={"w-full items-start"}>
<Text>
We use cookies and similar storage methods to keep track
of your session and how you are using our website. We do
not use third-party cookies.
</Text>
<Flex className={"w-full justify-end"}>
<Group>
<Link href={"/privacy"} className={"w-fit"}>
<Button color={"indigo"}>Learn more</Button>
</Link>
<Button
onClick={() => {
setHasAcceptedCookies(true);
notifications.hide("cookie-notice");
}}
>
I understand
</Button>
</Group>
</Flex>
</Stack>
),
});
}, [hasAcceptedCookies, setHasAcceptedCookies]);
useEffect(() => {
if (!hasAcceptedCookies) {
showCookieConsentNotification();
} else if (MATOMO_URL && MATOMO_SITE_ID) {
init({
url: MATOMO_URL,
siteId: MATOMO_SITE_ID,
});
}
}, [hasAcceptedCookies, showCookieConsentNotification]);

useEffect(() => {}, []);
return <></>;
};

export default MatomoTracker;
59 changes: 30 additions & 29 deletions src/components/general/NotificationsManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,36 @@ const handleNotifications = async (notificationsEntities: Notification[]) => {
const NotificationsManager = () => {
const userId = useUserId();
const infiniteNotificationsQuery = useInfiniteAggregatedNotifications();
useEffect(() => {
let eventSource: ReconnectingEventSource;
if (userId) {
const eventSource = new ReconnectingEventSource(targetSSEUrl, {
withCredentials: true,
max_retry_time: 5000,
});
eventSource.onopen = (conn) => {
console.log("Connected to notifications SSE: ", conn);
};
eventSource.onmessage = (message) => {
const notifications: Notification[] = JSON.parse(message.data);
handleNotifications(notifications)
.then(() => {
// Prevents unnecessary calls to notifications endpoint
if (notifications.length > 0) {
infiniteNotificationsQuery.invalidate();
}
})
.catch(console.error);
};
}

return () => {
if (eventSource) {
eventSource.close();
}
};
}, [infiniteNotificationsQuery, userId]);
// TODO: Check if this is causing trouble
// useEffect(() => {
// let eventSource: ReconnectingEventSource;
// if (userId) {
// const eventSource = new ReconnectingEventSource(targetSSEUrl, {
// withCredentials: true,
// max_retry_time: 5000,
// });
// eventSource.onopen = (conn) => {
// console.log("Connected to notifications SSE: ", conn);
// };
// eventSource.onmessage = (message) => {
// const notifications: Notification[] = JSON.parse(message.data);
// handleNotifications(notifications)
// .then(() => {
// // Prevents unnecessary calls to notifications endpoint
// if (notifications.length > 0) {
// infiniteNotificationsQuery.invalidate();
// }
// })
// .catch(console.error);
// };
// }
//
// return () => {
// if (eventSource) {
// eventSource.close();
// }
// };
// }, [infiniteNotificationsQuery, userId]);

return <Notifications />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ const SearchBarWithSelect = ({
)}
</Group>
}
mr={"0.5rem"}
/>
</Combobox.Target>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {
Box,
Button,
Center,
Group,
Popover,
ScrollArea,
Skeleton,
Stack,
Text,
Title,
} from "@mantine/core";
import { IconBell, IconBellFilled } from "@tabler/icons-react";
import useOnMobile from "@/components/general/hooks/useOnMobile";
Expand All @@ -17,6 +19,7 @@ import { useDisclosure, useIntersection } from "@mantine/hooks";
import { useMutation } from "@tanstack/react-query";
import { Notification, NotificationsService } from "@/wrapper/server";
import { useInfiniteAggregatedNotifications } from "@/components/notifications/hooks/useInfiniteAggregatedNotifications";
import CenteredLoading from "@/components/general/CenteredLoading";

const GlobalShellHeaderNotifications = () => {
const [isPopoverOpened, popoverUtils] = useDisclosure();
Expand Down Expand Up @@ -69,12 +72,6 @@ const GlobalShellHeaderNotifications = () => {
const hasNextPage =
lastElement != undefined && lastElement.pagination.hasNextPage;

const buildNotificationsSkeletons = useCallback(() => {
return new Array(5).fill(0).map((v, i) => {
return <Skeleton key={i} className={"w-full h-20"} />;
});
}, []);

const isEmpty =
!isLoading && (aggregations == undefined || aggregations.length === 0);

Expand Down Expand Up @@ -111,40 +108,107 @@ const GlobalShellHeaderNotifications = () => {
</Popover.Target>
<Popover.Dropdown p={0}>
<ScrollArea.Autosize mah={400}>
<Stack w={"100%"} h={"100%"} align={"center"} gap={4}>
<Stack w={"100%"} h={"100%"} align={"center"} gap={0}>
<Group
w={"100%"}
justify={"space-between"}
className={"p-2 mx-6 bg-[#111111]"}
>
<Group gap={5}>
{hasUnreadNotifications ? (
<IconBellFilled size={"1.8rem"} />
) : (
<IconBell size={"1.8rem"} />
)}
<Title size={"h4"}>Notifications</Title>
</Group>
<ActionIcon
variant={"transparent"}
onClick={() => {
const unreadNotifications = aggregations
?.filter((aggregation) => {
return aggregation.notifications.filter(
(notification) =>
!notification.isViewed,
);
})
.flatMap(
(aggregate) =>
aggregate.notifications,
);
if (
unreadNotifications &&
unreadNotifications.length > 0
) {
console.log(
`Marking ${unreadNotifications.length} notifications as read`,
);
notificationViewMutation.mutate(
unreadNotifications,
);
}
}}
>
<svg
width="28"
height="30"
viewBox="0 0 24 27"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 13.8463C0 12.5015 0.541725 11.2133 1.50287 10.2728L8.50286 3.42238C10.4464 1.52041 13.5536 1.52041 15.4971 3.42238L22.4971 10.2728C23.4583 11.2133 24 12.5015 24 13.8463V22C24 24.7614 21.7614 27 19 27H5C2.23858 27 0 24.7614 0 22V13.8463Z"
fill="#D9D9D9"
/>
<path
d="M6 16.6512L9.54098 20L18 12"
stroke="#F15025"
strokeWidth="2"
/>
</svg>
</ActionIcon>
</Group>
{aggregations?.map((aggregatedNotification, index) => {
const key = `${aggregatedNotification.sourceType}-${aggregatedNotification.sourceId}-${aggregatedNotification.sourceType}`;
const hasUnreadAggregationNotifications =
aggregatedNotification.notifications.some(
(notification) => !notification.isViewed,
);
if (
aggregatedNotification.notifications.length ===
0
) {
return null;
}

const key = aggregatedNotification.notifications
.map((notif) => notif.id)
.join(",");

return (
<Box
<AggregatedNotification
key={key}
className={"w-full h-full"}
aggregatedNotification={
aggregatedNotification
}
backgroundColor={
index === 0 || index % 2 === 0
? "normal"
: "darker"
}
onClick={() => {
popoverUtils.close();
if (
notificationViewMutation.isPending ||
isFetching ||
!hasUnreadAggregationNotifications
)
isFetching
) {
return;
}
notificationViewMutation.mutate(
aggregatedNotification.notifications,
);
}}
>
<AggregatedNotification
aggregatedNotification={
aggregatedNotification
}
/>
</Box>
/>
);
})}
{isFetching && buildNotificationsSkeletons()}
{isEmpty && <Text>No notifications.</Text>}
{isFetching && <CenteredLoading className={"my-4"} />}

{hasNextPage && (
<Center>
<Button
Expand Down
Loading

0 comments on commit dd722d1

Please sign in to comment.