From 862bae1a0429c7c4a76145803f1269d17bcb9183 Mon Sep 17 00:00:00 2001 From: ceddybi Date: Sun, 31 Mar 2024 11:11:02 -0400 Subject: [PATCH] feat(notifications): order, theme fix --- src/app/html/html.wrapper.tsx | 2 +- src/app/html/notifications/[slug]/route.ts | 32 +++++++++++++ src/components/navHTML/RightNav.tsx | 12 +++-- src/components/types.generated.ts | 14 ++++++ .../Notification/Notification.html.tsx | 33 ++++++++----- .../gql/notifications/notification.query.ts | 9 ++++ src/lib/hooksServer/notifications.ts | 48 ++++++++++++++++++- 7 files changed, 130 insertions(+), 20 deletions(-) create mode 100644 src/app/html/notifications/[slug]/route.ts diff --git a/src/app/html/html.wrapper.tsx b/src/app/html/html.wrapper.tsx index 9d5b389..99841dc 100644 --- a/src/app/html/html.wrapper.tsx +++ b/src/app/html/html.wrapper.tsx @@ -37,7 +37,7 @@ export const HtmlPageWrapper = ({ children, ...otherProps }: any) => { console.log('HtmlPageWrapper', { pathname, hasJs }); return ( - + {/* @ts-ignore */} { + try { + const id = params.slug; + const notifications = await readNotifications({ id }); + if (!notifications || isEmpty(notifications)) { + throw new Error('Notifications not found'); + } + const notification = notifications[0]; + if (!notification) { + throw new Error('Notification not found'); + } + const nextPath = getNotificationNextPath(notification); + return NextResponse.redirect(new URL(nextPath, req.url)); + } catch (error) { + console.log('An error occurred while fetching notifications', error); + return NextResponse.redirect(new URL('/html/notifications', req.url)); + } +}; diff --git a/src/components/navHTML/RightNav.tsx b/src/components/navHTML/RightNav.tsx index c9d30e9..10e5dad 100644 --- a/src/components/navHTML/RightNav.tsx +++ b/src/components/navHTML/RightNav.tsx @@ -62,6 +62,8 @@ const AuthRightNav = ({ (b) => (b.model || '').toLowerCase() === BadgeType.Notification, ); + const notificationBadgeCount = notificationBadge?.count || 0; + const avatarUri = cdnPath(currentUser && currentUser.avatar); // TODO default image const username = currentUser.username || ''; @@ -146,11 +148,11 @@ const AuthRightNav = ({ variant={ButtonIconType.Primary} /> - {notificationBadge && notificationBadge.count && ( -
- -
- )} + {notificationBadgeCount > 0 && ( +
+ +
+ )} diff --git a/src/components/types.generated.ts b/src/components/types.generated.ts index 2820078..700937d 100644 --- a/src/components/types.generated.ts +++ b/src/components/types.generated.ts @@ -992,6 +992,7 @@ export type Query = { getCityByState: Array; getFeePrices: FeePrices; getMoneyInEscrow?: Maybe; + getNotification?: Maybe; getOrderRating?: Maybe; getOrderRatings: OrderRatingOutputPagination; getPgpKey?: Maybe; @@ -1012,6 +1013,7 @@ export type Query = { posts: PostPagination; reactionGet: Reaction; reactionPagination: ReactionPagination; + readNotifications: Array; searchAdListingPublic?: Maybe; transactionById?: Maybe; transactionGet: Transaction; @@ -1126,6 +1128,11 @@ export type QueryGetCityByStateArgs = { }; +export type QueryGetNotificationArgs = { + id: Scalars['String']; +}; + + export type QueryGetOrderRatingArgs = { orderId: Scalars['String']; }; @@ -1247,6 +1254,13 @@ export type QueryReactionPaginationArgs = { }; +export type QueryReadNotificationsArgs = { + before?: InputMaybe; + id?: InputMaybe; + limit?: InputMaybe; +}; + + export type QuerySearchAdListingPublicArgs = { after?: InputMaybe; before?: InputMaybe; diff --git a/src/containers/Notification/Notification.html.tsx b/src/containers/Notification/Notification.html.tsx index 919afa1..d681cf8 100644 --- a/src/containers/Notification/Notification.html.tsx +++ b/src/containers/Notification/Notification.html.tsx @@ -1,6 +1,7 @@ 'use client'; import { + Background, CoreText, Display, FlexDirection, @@ -10,12 +11,13 @@ import { SVGAsset, } from '@uuixjs/uuixweb'; import { BorderRadius } from '@uuixjs/uuixweb-lib'; +import Link from 'next/link'; import React from 'react'; -import type { NotificationType } from '@/components/types.generated'; +import type { Notification } from '@/components/types.generated'; interface Props { - notifications?: NotificationType[]; + notifications?: Notification[]; // todo pagination } @@ -29,23 +31,30 @@ export const NotificationsContainerHtml = (props: Props) => { Notifications {notifications.map((notification) => ( - - - - {notification.message} - {' '} - + + + + {notification.message} + {' '} + + ))} ); diff --git a/src/lib/gql/notifications/notification.query.ts b/src/lib/gql/notifications/notification.query.ts index a2e3c1a..b6942e9 100644 --- a/src/lib/gql/notifications/notification.query.ts +++ b/src/lib/gql/notifications/notification.query.ts @@ -38,3 +38,12 @@ export const GET_NOTIFICATIONS = gql` } ${NotificationFragment} `; + +export const READ_NOTIFICATIONS = gql` + query ReadNotification($id: String, $before: DateTime, $limit: Float) { + data: readNotifications(id: $id, before: $before, limit: $limit) { + ...NotificationFragment + } + } + ${NotificationFragment} +`; diff --git a/src/lib/hooksServer/notifications.ts b/src/lib/hooksServer/notifications.ts index 504cf30..c086ab8 100644 --- a/src/lib/hooksServer/notifications.ts +++ b/src/lib/hooksServer/notifications.ts @@ -4,13 +4,19 @@ import pickBy from 'lodash/pickBy'; import type { Badge, + Notification, NotificationPagination, QueryGetBadgesArgs, QueryNotificationsArgs, + QueryReadNotificationsArgs, } from '@/components/types.generated'; import { getClient } from '../apollo-wrapper.server'; -import { GET_BADGES, GET_NOTIFICATIONS } from '../gql/notifications'; +import { + GET_BADGES, + GET_NOTIFICATIONS, + READ_NOTIFICATIONS, +} from '../gql/notifications'; export const fetchBadges = async ( props: QueryGetBadgesArgs, @@ -57,5 +63,43 @@ export const fetchNotifications = async ( return undefined; }; -// readNotification, +export const readNotifications = async ( + props: QueryReadNotificationsArgs, +): Promise => { + const [errorData, data] = await awaitTo( + getClient().query<{ data: Notification[] }>({ + query: READ_NOTIFICATIONS, + variables: pickBy(props, identity), + fetchPolicy: 'no-cache', + }), + ); + + if (errorData) { + console.error(errorData); + } + + if (data && data.data) { + return data.data.data; + } + + return undefined; +}; + +export const getNotificationNextPath = (notification: Notification): string => { + const notificationSource = (notification.source || '').toLowerCase(); + + switch (notificationSource) { + case 'user': + return `/html/u/${notification.sourceId}`; + case 'vendor': + return `/html/store/${notification.sourceId}`; + case 'ordertype': + case 'order': + return `/html/order/${notification.sourceId}`; + case 'notification': + default: + return '/html/notifications'; + } +}; + // deleteNotification, ....