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

mozilla / fx-private-relay / d4d9f278-d845-4992-8c81-4f3757c427a1

08 Sep 2025 02:07PM UTC coverage: 86.303% (-1.8%) from 88.121%
d4d9f278-d845-4992-8c81-4f3757c427a1

Pull #5842

circleci

joeherm
fix(deploy): Update CircleCI to use common Dockerfile for building frontend
Pull Request #5842: fix(deploy): Unify Dockerfiles

2744 of 3951 branches covered (69.45%)

Branch coverage included in aggregate %.

17910 of 19981 relevant lines covered (89.64%)

9.96 hits per line

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

35.9
/frontend/src/components/phones/dashboard/SendersPanelView.tsx
1
import styles from "./PhoneDashboard.module.scss";
1✔
2
import {
3
  ChevronLeftIcon,
4
  ForwardedCallIcon,
5
  ForwardedTextIcon,
6
  WarningFilledIcon,
7
} from "../../../components/Icons";
1✔
8
import Image from "../../Image";
1✔
9
import disabledSendersDataIllustration from "./images/sender-data-disabled-illustration.svg";
1✔
10
import emptySenderDataIllustration from "./images/sender-data-empty-illustration.svg";
1✔
11
import { useInboundContact } from "../../../hooks/api/inboundContact";
1✔
12
import { OutboundLink } from "react-ga";
1✔
13
import Link from "next/link";
1✔
14
import { formatPhone } from "../../../functions/formatPhone";
1✔
15
import { parseDate } from "../../../functions/parseDate";
1✔
16
import { getLocale } from "../../../functions/getLocale";
1✔
17
import { useL10n } from "../../../hooks/l10n";
1✔
18
import { useMetrics } from "../../../hooks/metrics";
1✔
19

20
export type Props = {
21
  type: "primary" | "disabled" | "empty";
22
  back_btn: () => void;
23
};
24

25
export const SendersPanelView = (props: Props) => {
1✔
26
  const l10n = useL10n();
×
27
  const metricsEnabled = useMetrics();
×
28
  const inboundContactData = useInboundContact();
×
29
  const inboundArray = inboundContactData.data;
×
30
  const dateTimeFormatter = new Intl.DateTimeFormat(getLocale(l10n), {
×
31
    dateStyle: "short",
32
    timeStyle: "short",
33
  });
34

35
  const emptyCallerSMSSendersPanel = (
36
    <div className={styles["senders-panel"]}>
37
      <Image
38
        src={emptySenderDataIllustration}
39
        alt="Empty Senders Data Illustration"
40
        width={130}
41
      />
42
      <p className={styles["senders-panel-body"]}>
43
        {l10n.getString("phone-dashboard-sender-empty-body")}
44
      </p>
45
    </div>
46
  );
47

48
  const updateSettingsWithMetrics = (
49
    <OutboundLink
50
      to="/accounts/settings/"
51
      eventLabel="Update Settings"
52
      target="_blank"
53
      rel="noopener noreferrer"
54
    >
55
      {l10n.getString("phone-dashboard-sender-disabled-update-settings")}
56
    </OutboundLink>
57
  );
58

59
  const updateSettingsWithoutMetrics = (
60
    <Link href="/accounts/settings/" target="_blank" rel="noopener noreferrer">
61
      {l10n.getString("phone-dashboard-sender-disabled-update-settings")}
62
    </Link>
63
  );
64

65
  const disabledCallerSMSSendersPanel = (
66
    <div className={styles["senders-panel"]}>
67
      <Image
68
        src={disabledSendersDataIllustration}
69
        alt="Disabled Senders Data Illustration"
70
        width={130}
71
      />
72
      <p className={styles["senders-panel-body"]}>
73
        <WarningFilledIcon
74
          alt=""
75
          className={styles["warning-icon"]}
76
          width={20}
77
          height={20}
78
        />
79
        {l10n.getString("phone-dashboard-sender-disabled-body")}
80
      </p>
81
      <div className={styles["update-settings-cta"]}>
82
        {metricsEnabled
×
83
          ? updateSettingsWithMetrics
84
          : updateSettingsWithoutMetrics}
85
      </div>
86
    </div>
87
  );
88

89
  const inboundContactArray =
90
    inboundContactData &&
×
91
    inboundArray
92
      ?.sort(
93
        (a, b) =>
94
          // Sort by last sent date
95
          parseDate(b.last_inbound_date).getTime() -
×
96
          parseDate(a.last_inbound_date).getTime(),
97
      )
98
      .map((data) => {
99
        return (
×
100
          <tr
101
            key={data.id}
102
            className={data.blocked ? styles["greyed-contact"] : ""}
×
103
          >
104
            <td className={styles["sender-number"]}>
105
              {formatPhone(data.inbound_number ?? "")}
×
106
            </td>
107
            <td
108
              className={`${styles["sender-date"]} ${styles["sender-date-wrapper"]}`}
109
            >
110
              {data.last_inbound_type === "text" && (
×
111
                <ForwardedTextIcon
112
                  alt="Last received a text"
113
                  className={styles["forwarded-type-icon"]}
114
                  width={20}
115
                  height={12}
116
                />
117
              )}
118
              {data.last_inbound_type === "call" && (
×
119
                <ForwardedCallIcon
120
                  alt="Last received a call"
121
                  className={styles["forwarded-type-icon"]}
122
                  width={20}
123
                  height={15}
124
                />
125
              )}
126
              {dateTimeFormatter.format(parseDate(data.last_inbound_date))}
127
            </td>
128
            <td className={styles["sender-controls"]}>
129
              <button
130
                onClick={() =>
131
                  inboundContactData.setForwardingState(!data.blocked, data.id)
×
132
                }
133
                className={styles["block-btn"]}
134
              >
135
                {data.blocked ? "Unblock" : "Block"}
×
136
              </button>
137
            </td>
138
          </tr>
139
        );
140
      });
141

142
  const senderLogsPanel = (
143
    <table className={styles["caller-sms-senders-table"]}>
144
      <thead>
145
        <tr className={styles["greyed-contact"]}>
146
          <th>{l10n.getString("phone-dashboard-sender-table-title-sender")}</th>
147
          <th>
148
            {l10n.getString("phone-dashboard-sender-table-title-activity")}
149
          </th>
150
          <th>{l10n.getString("phone-dashboard-sender-table-title-action")}</th>
151
        </tr>
152
      </thead>
153
      <tbody>{inboundContactArray}</tbody>
154
    </table>
155
  );
156

157
  return (
158
    <div id="secondary-panel" className={styles["dashboard-card"]}>
159
      <div className={styles["dashboard-card-caller-sms-senders-header"]}>
160
        <span>
161
          <button
162
            type="button"
163
            onClick={() => props.back_btn()}
×
164
            className={styles["caller-sms-logs-back-btn"]}
165
          >
166
            <ChevronLeftIcon
167
              alt="Back to Primary Dashboard"
168
              className={styles["nav-icon"]}
169
              width={20}
170
              height={20}
171
            />
172
          </button>
173
        </span>
174
        <span className={styles["caller-sms-logs-title"]}>
175
          {l10n.getString("phone-dashboard-senders-header")}
176
        </span>
177
        <span></span>
178
      </div>
179
      {props.type === "primary" && <>{senderLogsPanel}</>}
×
180
      {props.type === "disabled" && <>{disabledCallerSMSSendersPanel}</>}
×
181
      {props.type === "empty" && <>{emptyCallerSMSSendersPanel}</>}
×
182
    </div>
183
  );
184
};
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

© 2025 Coveralls, Inc