• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atlp-rwanda / knights-ecomm-fe / 10036401392

22 Jul 2024 07:17AM UTC coverage: 90.671% (+0.02%) from 90.653%
10036401392

push

github

web-flow
Merge pull request #72 from atlp-rwanda/feat-In-App-Notifications

Implement In-App-Notificatons

907 of 1153 branches covered (78.66%)

Branch coverage included in aggregate %.

392 of 423 new or added lines in 9 files covered. (92.67%)

12 existing lines in 2 files now uncovered.

9677 of 10520 relevant lines covered (91.99%)

10.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.18
/src/components/Notification/Notification.tsx
1
import React, { useEffect, useState } from 'react';
1✔
2
import { setOpenNotification, setSelectedNotificationsIds } from '../../redux/reducers/notification';
1✔
3
import { useDispatch, useSelector } from 'react-redux';
1✔
4
import OneNotification from './OneNotification';
1✔
5
import { RootState } from '../../redux/store';
1✔
6
import axios from 'axios';
1✔
7
import toast from 'react-hot-toast';
1✔
8
import { getConfig } from '../../redux/actions/cartAction';
1✔
9
import { deleteNotifications } from '../../utils/notificationsFunctios/deleteNotifications';
1✔
10

1✔
11
function Notification() {
1✔
12
  const { userToken } = useSelector((state: RootState) => state.auth);
1✔
13
  const dispatch = useDispatch();
1✔
14
  const { allNotifications, selectedNotificationsIds } = useSelector((state: RootState) => state.notification);
16✔
15
  const [notificationDivs, setNotificationDivs] = useState<JSX.Element[]>([]);
16✔
16
  const notificationIds: string[] = [];
16✔
17
  const config = getConfig();
16✔
18

16✔
19
  const handleNotificationPopup = () => {
16✔
20
    dispatch(setOpenNotification(false));
16✔
21
  };
16✔
22

16✔
23
  const handleSelectAll = (event: React.ChangeEvent<HTMLInputElement>) => {
16✔
24
    const checked = event.target.checked;
16✔
25
    if (checked) {
1✔
26
      allNotifications.forEach((notification) => {
1✔
27
        notificationIds.push(notification.id);
16✔
28
      });
16✔
29
      dispatch(setSelectedNotificationsIds(notificationIds));
2✔
30
    } else if (!checked) {
2✔
31
      dispatch(setSelectedNotificationsIds([]));
2✔
32
    }
4✔
33
  };
2✔
34

2✔
35
  const handleDeletingNotifications = () => {
2!
NEW
36
    if (selectedNotificationsIds.length === 0) {
×
NEW
37
      toast.error('Please select notifications to delete before deleting');
×
38
    } else {
2✔
39
      deleteNotifications(userToken, selectedNotificationsIds);
16✔
40
      dispatch(setSelectedNotificationsIds([]));
16✔
41
    }
2✔
42
  };
1✔
43

1✔
44
  const updateSelectedNotifications = async (event: React.MouseEvent<HTMLDivElement>) => {
1✔
45
    event.preventDefault();
1✔
46
    if (selectedNotificationsIds.length > 0) {
1✔
47
      try {
2✔
48
        const updateSelectedNotifications = await axios.put(
16✔
49
          `${import.meta.env.VITE_APP_API_URL}/notification`,
16✔
50
          { notificationIds: selectedNotificationsIds },
3✔
51
          config
3✔
52
        );
2✔
53

2✔
54
        if (updateSelectedNotifications.data.status === 'success') {
2✔
55
          toast.success('Selected notifications marked as read');
2✔
56
          dispatch(setSelectedNotificationsIds([]));
2✔
57
        } else {
2✔
58
          toast.error('Failed to update selected notifications');
1✔
59
        }
1✔
60
      } catch (error) {
1✔
61
        console.log('Failed to update selected notifications', error);
1✔
62
        toast.error('Failed to update selected notifications');
2!
NEW
63
      }
×
NEW
64
    } else {
×
65
      toast.error('No notifications selected');
2✔
66
    }
1✔
67
  };
1✔
68

1✔
69
  useEffect(() => {
3✔
70
    const notificaionJSX: JSX.Element[] = [];
1✔
71
    allNotifications.forEach((notification, index) => {
1✔
72
      notificaionJSX.push(<OneNotification noficationProp={notification} key={index} />);
3✔
73
    });
16✔
74
    setNotificationDivs(notificaionJSX);
16✔
75
  }, [allNotifications]);
8✔
76

8✔
77
  return (
13✔
78
    <div className="fixed animate-slideInFromTop inset-0 z-40 flex pt-[90px] px-4 xmd:pt-[70px] xmd:px-16 lg:pt-[80px] lg:px-36 items-center justify-center bg-black bg-opacity-50 transition-opacity duration-300 ease-out">
8✔
79
      <div className="bg-white h-[550px] w-full p-8 pb-2 rounded-lg shadow-lg transform transition-transform duration-500 ease-in-out flex flex-col gap-4">
8✔
80
        <div className="flex justify-between items-center">
16✔
81
          <div className="text-[18px] font-bold">Notification</div>
16✔
82
          <div onClick={handleNotificationPopup} className="text-[25px] font-medium cursor-pointer">
16✔
83
            X
16✔
84
          </div>
16✔
85
        </div>
16✔
86

16✔
87
        {notificationDivs.length > 0 && (
16✔
88
          <div className="flex gap-3 items-center px-4">
16✔
89
            <input
16✔
90
              style={{ height: '1.2rem', width: '1.2rem', cursor: 'pointer' }}
16✔
91
              type="checkbox"
16✔
92
              id="selectAll"
16✔
93
              checked={allNotifications.length === selectedNotificationsIds.length}
7✔
94
              onChange={handleSelectAll}
7✔
95
              name="selectAll"
7✔
96
            />
7✔
97
            <label className="cursor-pointer" htmlFor="selectAll">
7✔
98
              Select All
7✔
99
            </label>
7✔
100
          </div>
7✔
101
        )}
7✔
102
        <div className="w-full h-full overflow-y-scroll overflow-x-auto">
7✔
103
          <div className="w-[600px] xmd:w-full flex flex-col gap-2">
7✔
104
            {notificationDivs.length > 0 && notificationDivs}
7✔
105
            {notificationDivs.length === 0 && <p className="text-center">You have no notifications</p>}
7✔
106
          </div>
16✔
107
        </div>
16✔
108
        {allNotifications.length > 0 && (
16✔
109
          <div className="py-2 text-[15px] flex flex-col gap-y-2 items-center sm:flex-row justify-between">
16✔
110
            <div onClick={updateSelectedNotifications} className="inline-block hover:underline cursor-pointer">
16✔
111
              Mark all selected as read
9✔
112
            </div>
16✔
113
            <div onClick={handleDeletingNotifications} className="inline-block hover:underline cursor-pointer">
16✔
114
              Clear selected
16✔
115
            </div>
16✔
116
          </div>
14✔
117
        )}
14✔
118
      </div>
14✔
119
    </div>
14✔
120
  );
14✔
121
}
14✔
122

14✔
123
export default Notification;
14✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc