@upsnap/strapi 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { Layouts, Page } from "@strapi/strapi/admin";
3
3
  import { NavLink, useNavigate, useParams, Routes, Route } from "react-router-dom";
4
- import { SubNav, SubNavHeader, SubNavSection, SubNavLink, Box, Table, Thead, Tr, Th, Checkbox, Typography, VisuallyHidden, Tbody, Td, Flex, Badge, IconButton, Card, CardHeader, Switch, CardBody, CardContent, SingleSelect, SingleSelectOption, Accordion, TextInput, Loader, Tooltip, Field, Button, Dialog, Link as Link$1, Modal, SimpleMenu, MenuItem, Tabs, CardTitle, CardSubtitle, CardBadge, Main, Divider, Grid, MultiSelect, MultiSelectOption } from "@strapi/design-system";
4
+ import { SubNav, SubNavHeader, SubNavSection, SubNavLink, Box, Table, Thead, Tr, Th, Checkbox, Typography, VisuallyHidden, Tbody, Td, Flex, Badge, IconButton, Card, CardHeader, Switch, CardBody, CardContent, SingleSelect, SingleSelectOption, Accordion, TextInput, Loader, Tooltip, Field, Button, Dialog, Alert, Modal, SimpleMenu, MenuItem, Tabs, Divider, Link as Link$1, CardTitle, CardSubtitle, CardBadge, Main, Grid, MultiSelect, MultiSelectOption } from "@strapi/design-system";
5
5
  import { House, Earth, Lock, Link, Palette, Globe, ExternalLink, Monitor, Cog, Pencil, Trash, Search, Cross, ChevronDown, Plus, EyeStriked, Eye, Graph, MinusCircle, Play, More, CrossCircle, SealCheck, ArrowsCounterClockwise, ArrowRight, CheckCircle, Information, ArrowDown, Rocket, ArrowLeft } from "@strapi/icons";
6
6
  import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
7
7
  import { toast, ToastContainer } from "react-toastify";
@@ -124,7 +124,6 @@ const PLAN_LIMITS = {
124
124
  max_status_pages: 1
125
125
  }
126
126
  };
127
- const DASHBOARD_URL = "https://upsnap.ai";
128
127
  const STATS_PAGE_URL = "https://stats.upsnap.ai";
129
128
  const DEFAULT_REGION = {
130
129
  id: "default",
@@ -341,6 +340,22 @@ async function getPrimaryMonitorId() {
341
340
  return null;
342
341
  }
343
342
  }
343
+ async function handleLogout() {
344
+ try {
345
+ await setPrimaryMonitorId("");
346
+ const res = await request("/settings", {
347
+ method: "POST",
348
+ data: { token: null, logOut: true }
349
+ });
350
+ if (res.ok) {
351
+ return true;
352
+ }
353
+ return false;
354
+ } catch (err) {
355
+ console.log("Error while logging out ", err);
356
+ return;
357
+ }
358
+ }
344
359
  const STORAGE_KEY = "selectedMonitor";
345
360
  function getUserData() {
346
361
  if (typeof window === "undefined") return null;
@@ -419,6 +434,7 @@ function MonitorsTable({
419
434
  const [defaultEmail, setDefaultEmail] = useState();
420
435
  const isInternalUpdate = useRef(false);
421
436
  const [primaryMonitorId, setPrimaryMonitorIdState] = useState(null);
437
+ const navigate = useNavigate();
422
438
  useEffect(() => {
423
439
  async function fetchPrimaryMonitorId() {
424
440
  try {
@@ -466,6 +482,8 @@ function MonitorsTable({
466
482
  if (result) {
467
483
  toast.success("Primary monitor set successfully");
468
484
  setPrimaryMonitorIdState(monitor.id);
485
+ navigate("/plugins/upsnap/dashboard");
486
+ return;
469
487
  } else {
470
488
  toast.error("Failed to set primary monitor");
471
489
  }
@@ -4831,6 +4849,19 @@ const statusPageSchema = object({
4831
4849
  name: string().min(1, "Name is required").max(100, "Name must be less than 100 characters"),
4832
4850
  monitor_ids: array(string()).min(1, "At least one monitor is required")
4833
4851
  });
4852
+ const loginSchema = object({
4853
+ email: string().email("Invalid email address"),
4854
+ password: string().min(1, "Password is required")
4855
+ });
4856
+ const registerSchema = object({
4857
+ fullName: string().min(2, "Full name must be at least 2 characters"),
4858
+ email: string().email("Invalid email address"),
4859
+ password: string().min(8, "Password must be at least 8 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/\d/, "Password must contain at least one number"),
4860
+ confirmPassword: string().min(1, "Confirm password is required")
4861
+ }).refine((data) => data.password === data.confirmPassword, {
4862
+ message: "Passwords do not match",
4863
+ path: ["confirmPassword"]
4864
+ });
4834
4865
  const serviceConfigSchema = object({
4835
4866
  enabled: boolean(),
4836
4867
  monitor_interval: number().optional(),
@@ -6409,6 +6440,13 @@ function Monitors({ onTabChange }) {
6409
6440
  const [bulkDeleteIds, setBulkDeleteIds] = useState([]);
6410
6441
  const [bulkDeleteModalOpen, setBulkDeleteModalOpen] = useState(false);
6411
6442
  const userDetails = getUserData();
6443
+ const [alertMessage, setAlertMessage] = useState("");
6444
+ useEffect(() => {
6445
+ (async () => {
6446
+ const fetchedMonitorId = await getPrimaryMonitorId();
6447
+ if (!fetchedMonitorId) setAlertMessage("Please select a primary monitor to continue!");
6448
+ })();
6449
+ }, []);
6412
6450
  const load = async () => {
6413
6451
  try {
6414
6452
  setLoading(true);
@@ -6518,6 +6556,7 @@ function Monitors({ onTabChange }) {
6518
6556
  }
6519
6557
  };
6520
6558
  return /* @__PURE__ */ jsxs(Box, { width: "100%", children: [
6559
+ alertMessage && /* @__PURE__ */ jsx(Box, { width: "100%", padding: 3, children: /* @__PURE__ */ jsx(Alert, { closeLabel: "Close", title: "", children: alertMessage.charAt(0).toUpperCase() + alertMessage.slice(1) }) }),
6521
6560
  !showEdit && /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", gap: 4, children: [
6522
6561
  /* @__PURE__ */ jsxs(
6523
6562
  Flex,
@@ -6593,56 +6632,6 @@ function Monitors({ onTabChange }) {
6593
6632
  )
6594
6633
  ] });
6595
6634
  }
6596
- function APIToken() {
6597
- const [token, setToken] = useState("");
6598
- const [loading, setLoading] = useState(false);
6599
- const navigate = useNavigate();
6600
- useEffect(() => {
6601
- request("/settings", {
6602
- method: "GET"
6603
- }).then((res) => {
6604
- setToken(res.token || "");
6605
- });
6606
- }, []);
6607
- const save = async () => {
6608
- setLoading(true);
6609
- await request("/settings", {
6610
- method: "POST",
6611
- data: { token }
6612
- }).then((res) => {
6613
- if (!res.ok) {
6614
- toast.error(res.error || "Failed to save token");
6615
- setLoading(false);
6616
- return;
6617
- }
6618
- toast.success("Token saved successfully");
6619
- navigate("/plugins/upsnap/dashboard");
6620
- });
6621
- setLoading(false);
6622
- };
6623
- return /* @__PURE__ */ jsxs(Box, { padding: 3, children: [
6624
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "start", children: [
6625
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: "Token Settings" }),
6626
- /* @__PURE__ */ jsxs(Typography, { variant: "omega", children: [
6627
- "Enter the Upsnap API Key and save to enable Healthcheck settings. To access the API key, please visit the",
6628
- " ",
6629
- /* @__PURE__ */ jsx(Link$1, { href: DASHBOARD_URL, isExternal: true, children: "Upsnap Dashboard" })
6630
- ] })
6631
- ] }),
6632
- /* @__PURE__ */ jsxs(Box, { marginTop: 6, width: "100%", children: [
6633
- /* @__PURE__ */ jsx(
6634
- TextInput,
6635
- {
6636
- placeholder: "API Token",
6637
- type: "password",
6638
- value: token,
6639
- onChange: (e) => setToken(e.target.value)
6640
- }
6641
- ),
6642
- /* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(Button, { loading, onClick: save, children: "Save" }) })
6643
- ] })
6644
- ] });
6645
- }
6646
6635
  const getNestedValue = (obj, path) => {
6647
6636
  return path.split(".").reduce((current, key) => current?.[key], obj);
6648
6637
  };
@@ -7503,7 +7492,7 @@ function SettingsTabs({
7503
7492
  activeTab,
7504
7493
  onTabChange
7505
7494
  }) {
7506
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: activeTab, value: activeTab, onValueChange: onTabChange, children: [
7495
+ return /* @__PURE__ */ jsx(Box, { padding: 8, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardBody, { children: /* @__PURE__ */ jsx(CardContent, { width: "100%", children: /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: activeTab, value: activeTab, onValueChange: onTabChange, children: [
7507
7496
  /* @__PURE__ */ jsx(Tabs.List, { "aria-label": "Manage your attribute", children: /* @__PURE__ */ jsx(
7508
7497
  Flex,
7509
7498
  {
@@ -7516,28 +7505,389 @@ function SettingsTabs({
7516
7505
  ) }),
7517
7506
  /* @__PURE__ */ jsxs(Tabs.Content, { value: activeTab, children: [
7518
7507
  activeTab === "monitors" && /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(Monitors, { onTabChange }) }),
7519
- activeTab === "notification_channels" && /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(IntegrationsPage, {}) }),
7520
- activeTab === "api_key" && /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(APIToken, {}) })
7508
+ activeTab === "notification_channels" && /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(IntegrationsPage, {}) })
7521
7509
  ] })
7522
- ] }) });
7510
+ ] }) }) }) }) });
7511
+ }
7512
+ function LogInForm({
7513
+ setShowLoginForm,
7514
+ setShowRegisterForm,
7515
+ setShowExpiredMessage
7516
+ }) {
7517
+ const [email2, setEmail] = useState("");
7518
+ const [password, setPassword] = useState("");
7519
+ const [errors, setErrors] = useState(null);
7520
+ const [loading, setLoading] = useState(false);
7521
+ const [forgotPasswordError, setForgotPasswordError] = useState("");
7522
+ const navigate = useNavigate();
7523
+ const handleSubmit = (e) => {
7524
+ e.preventDefault();
7525
+ setLoading(true);
7526
+ const result = loginSchema.safeParse({ email: email2, password });
7527
+ if (!result.success) {
7528
+ setErrors(result.error);
7529
+ setLoading(false);
7530
+ return;
7531
+ }
7532
+ setErrors(null);
7533
+ request("/login", {
7534
+ method: "POST",
7535
+ data: {
7536
+ email: email2,
7537
+ password
7538
+ }
7539
+ }).then((res) => {
7540
+ if (res?.ok) {
7541
+ toast.success("Login Successful");
7542
+ navigate("/plugins/upsnap/dashboard");
7543
+ return;
7544
+ }
7545
+ toast.error(res?.message || "Not able to login, please try again.");
7546
+ setShowExpiredMessage(res?.message);
7547
+ }).catch((err) => {
7548
+ toast.error("Not able to login, please try again.");
7549
+ }).finally(() => {
7550
+ setLoading(false);
7551
+ });
7552
+ };
7553
+ const handleForgotPassword = () => {
7554
+ if (!email2) {
7555
+ setForgotPasswordError("Please enter the email.");
7556
+ return;
7557
+ }
7558
+ setForgotPasswordError("");
7559
+ request("/forgot-password", {
7560
+ method: "POST",
7561
+ data: {
7562
+ email: email2
7563
+ }
7564
+ }).then((res) => {
7565
+ if (res?.ok) {
7566
+ toast.success(res?.message);
7567
+ return;
7568
+ }
7569
+ toast.error(res?.message || "Not able to login, please try again.");
7570
+ setShowExpiredMessage(res?.message);
7571
+ }).catch((err) => {
7572
+ toast.error("Not able to send email, please try again.");
7573
+ }).finally(() => {
7574
+ setLoading(false);
7575
+ });
7576
+ };
7577
+ return /* @__PURE__ */ jsx(Box, { margin: "auto", width: { initial: "100%", medium: "55%" }, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardBody, { children: /* @__PURE__ */ jsx(CardContent, { width: "100%", children: /* @__PURE__ */ jsxs(Box, { padding: 4, width: "100%", children: [
7578
+ /* @__PURE__ */ jsxs(
7579
+ Flex,
7580
+ {
7581
+ marginBottom: 3,
7582
+ direction: "column",
7583
+ gap: 1,
7584
+ justifyContent: "start",
7585
+ alignItems: "start",
7586
+ children: [
7587
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Sign In" }),
7588
+ /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", marginBottom: 3, children: "Enter your email and password to Sign In." })
7589
+ ]
7590
+ }
7591
+ ),
7592
+ /* @__PURE__ */ jsx(Divider, { marginBottom: 3 }),
7593
+ /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, width: "100%", children: [
7594
+ /* @__PURE__ */ jsxs(
7595
+ Field.Root,
7596
+ {
7597
+ width: "100%",
7598
+ error: errors?.issues.find((issue2) => issue2.path[0] === "email")?.message || forgotPasswordError,
7599
+ required: true,
7600
+ children: [
7601
+ /* @__PURE__ */ jsx(Field.Label, { children: "Email" }),
7602
+ /* @__PURE__ */ jsx(
7603
+ Field.Input,
7604
+ {
7605
+ type: "email",
7606
+ placeholder: "example@gmail.com",
7607
+ value: email2,
7608
+ onChange: (e) => setEmail(e.target.value)
7609
+ }
7610
+ ),
7611
+ /* @__PURE__ */ jsx(Field.Error, {})
7612
+ ]
7613
+ }
7614
+ ),
7615
+ /* @__PURE__ */ jsxs(
7616
+ Field.Root,
7617
+ {
7618
+ width: "100%",
7619
+ error: errors?.issues.find((issue2) => issue2.path[0] === "password")?.message,
7620
+ required: true,
7621
+ children: [
7622
+ /* @__PURE__ */ jsx(Field.Label, { children: "Password" }),
7623
+ /* @__PURE__ */ jsx(
7624
+ Field.Input,
7625
+ {
7626
+ type: "password",
7627
+ placeholder: "Enter a password",
7628
+ value: password,
7629
+ onChange: (e) => setPassword(e.target.value)
7630
+ }
7631
+ ),
7632
+ /* @__PURE__ */ jsx(Field.Error, {})
7633
+ ]
7634
+ }
7635
+ ),
7636
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(Flex, { justifyContent: "end", marginTop: 4, children: /* @__PURE__ */ jsx(
7637
+ Link$1,
7638
+ {
7639
+ onClick: (e) => {
7640
+ e?.preventDefault();
7641
+ handleForgotPassword();
7642
+ },
7643
+ children: "forgot password?"
7644
+ }
7645
+ ) }) }),
7646
+ /* @__PURE__ */ jsx(Flex, { width: "100%", justifyContent: "end", marginTop: 3, children: /* @__PURE__ */ jsx(Button, { size: "L", type: "submit", loading, children: "Sign In" }) })
7647
+ ] }) }),
7648
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", marginTop: 4, children: /* @__PURE__ */ jsx(
7649
+ Link$1,
7650
+ {
7651
+ onClick: (e) => {
7652
+ e?.preventDefault();
7653
+ setShowLoginForm(false);
7654
+ setShowRegisterForm(true);
7655
+ },
7656
+ children: "Not registered? Create account"
7657
+ }
7658
+ ) })
7659
+ ] }) }) }) }) });
7660
+ }
7661
+ function RegisterForm({
7662
+ setShowRegisterForm,
7663
+ setShowLoginForm,
7664
+ setShowExpiredMessage
7665
+ }) {
7666
+ const [fullName, setFullName] = useState("");
7667
+ const [email2, setEmail] = useState("");
7668
+ const [password, setPassword] = useState("");
7669
+ const [confirmPassword, setConfirmPassword] = useState("");
7670
+ const [confirmPasswordError, setConfirmPasswordError] = useState("");
7671
+ const [errors, setErrors] = useState(null);
7672
+ const [loading, setLoading] = useState(false);
7673
+ const navigate = useNavigate();
7674
+ const handleSubmit = (e) => {
7675
+ e.preventDefault();
7676
+ setLoading(true);
7677
+ const result = registerSchema.safeParse({ email: email2, password, fullName, confirmPassword });
7678
+ if (!result.success) {
7679
+ setErrors(result.error);
7680
+ setLoading(false);
7681
+ return;
7682
+ }
7683
+ setErrors(null);
7684
+ const domainUrl = window.strapi?.backendURL || window.location.origin;
7685
+ request("/signup", {
7686
+ method: "POST",
7687
+ data: {
7688
+ email: email2,
7689
+ password,
7690
+ fullName,
7691
+ source: "strapi",
7692
+ site_url: domainUrl
7693
+ }
7694
+ }).then((res) => {
7695
+ if (res?.ok) {
7696
+ toast.success(res?.message || "UpSnap Connected.");
7697
+ toast.success("Your site is now being monitored every 5 minutes.");
7698
+ navigate("/plugins/upsnap/dashboard");
7699
+ return;
7700
+ }
7701
+ toast.error("Not able to register, please try again.");
7702
+ }).catch((err) => {
7703
+ toast.error("Not able to register, please try again.");
7704
+ }).finally(() => {
7705
+ setLoading(false);
7706
+ });
7707
+ };
7708
+ return /* @__PURE__ */ jsx(Box, { margin: "auto", width: { initial: "100%", medium: "55%" }, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardBody, { children: /* @__PURE__ */ jsx(CardContent, { width: "100%", children: /* @__PURE__ */ jsxs(Box, { padding: 4, width: "100%", children: [
7709
+ /* @__PURE__ */ jsxs(
7710
+ Flex,
7711
+ {
7712
+ marginBottom: 3,
7713
+ direction: "column",
7714
+ gap: 1,
7715
+ justifyContent: "start",
7716
+ alignItems: "start",
7717
+ children: [
7718
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Register" }),
7719
+ /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", marginBottom: 3, children: "Create a free UpSnap beta account to start monitoring your site." })
7720
+ ]
7721
+ }
7722
+ ),
7723
+ /* @__PURE__ */ jsx(Divider, { marginBottom: 3 }),
7724
+ /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, width: "100%", children: [
7725
+ /* @__PURE__ */ jsxs(
7726
+ Field.Root,
7727
+ {
7728
+ width: "100%",
7729
+ error: errors?.issues.find((issue2) => issue2.path[0] === "fullName")?.message,
7730
+ required: true,
7731
+ children: [
7732
+ /* @__PURE__ */ jsx(Field.Label, { children: "Full Name" }),
7733
+ /* @__PURE__ */ jsx(
7734
+ Field.Input,
7735
+ {
7736
+ type: "text",
7737
+ placeholder: "Ted Lasso",
7738
+ value: fullName,
7739
+ onChange: (e) => setFullName(e.target.value)
7740
+ }
7741
+ ),
7742
+ /* @__PURE__ */ jsx(Field.Error, {})
7743
+ ]
7744
+ }
7745
+ ),
7746
+ /* @__PURE__ */ jsxs(
7747
+ Field.Root,
7748
+ {
7749
+ width: "100%",
7750
+ error: errors?.issues.find((issue2) => issue2.path[0] === "email")?.message,
7751
+ required: true,
7752
+ children: [
7753
+ /* @__PURE__ */ jsx(Field.Label, { children: "Email" }),
7754
+ /* @__PURE__ */ jsx(
7755
+ Field.Input,
7756
+ {
7757
+ type: "email",
7758
+ placeholder: "example@gmail.com",
7759
+ value: email2,
7760
+ onChange: (e) => setEmail(e.target.value)
7761
+ }
7762
+ ),
7763
+ /* @__PURE__ */ jsx(Field.Error, {})
7764
+ ]
7765
+ }
7766
+ ),
7767
+ /* @__PURE__ */ jsxs(
7768
+ Field.Root,
7769
+ {
7770
+ width: "100%",
7771
+ error: errors?.issues.find((issue2) => issue2.path[0] === "password")?.message,
7772
+ required: true,
7773
+ children: [
7774
+ /* @__PURE__ */ jsx(Field.Label, { children: "Password" }),
7775
+ /* @__PURE__ */ jsx(
7776
+ Field.Input,
7777
+ {
7778
+ type: "password",
7779
+ placeholder: "Enter a password",
7780
+ value: password,
7781
+ onChange: (e) => {
7782
+ const value = e.target.value;
7783
+ setPassword(value);
7784
+ }
7785
+ }
7786
+ ),
7787
+ /* @__PURE__ */ jsx(Field.Error, {})
7788
+ ]
7789
+ }
7790
+ ),
7791
+ /* @__PURE__ */ jsxs(
7792
+ Field.Root,
7793
+ {
7794
+ width: "100%",
7795
+ error: errors?.issues.find((issue2) => issue2.path[0] === "confirmPassword")?.message || confirmPasswordError,
7796
+ required: true,
7797
+ children: [
7798
+ /* @__PURE__ */ jsx(Field.Label, { children: "Confirm Password" }),
7799
+ /* @__PURE__ */ jsx(
7800
+ Field.Input,
7801
+ {
7802
+ type: "password",
7803
+ placeholder: "Confirm password",
7804
+ value: confirmPassword,
7805
+ onChange: (e) => {
7806
+ const value = e.target.value;
7807
+ setConfirmPassword(value);
7808
+ if (password && value && password !== value) {
7809
+ setConfirmPasswordError("Passwords do not match");
7810
+ } else {
7811
+ setConfirmPasswordError("");
7812
+ }
7813
+ }
7814
+ }
7815
+ ),
7816
+ /* @__PURE__ */ jsx(Field.Error, {})
7817
+ ]
7818
+ }
7819
+ ),
7820
+ /* @__PURE__ */ jsx(Flex, { width: "100%", justifyContent: "end", marginTop: 3, children: /* @__PURE__ */ jsx(Button, { size: "L", type: "submit", loading, children: "Start Free Beta Monitoring" }) })
7821
+ ] }) }),
7822
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", marginTop: 4, children: /* @__PURE__ */ jsx(
7823
+ Link$1,
7824
+ {
7825
+ onClick: (e) => {
7826
+ e?.preventDefault();
7827
+ setShowRegisterForm(false);
7828
+ setShowLoginForm(true);
7829
+ },
7830
+ children: "Already have an account?"
7831
+ }
7832
+ ) })
7833
+ ] }) }) }) }) });
7523
7834
  }
7524
7835
  function Settings() {
7525
7836
  const [activeTab, setActiveTab] = useState("monitors");
7837
+ const [showLogin, setShowLogin] = useState(false);
7838
+ const [showRegister, setShowRegister] = useState(false);
7839
+ const [showExpiredMessage, setShowExpiredMessage] = useState("");
7840
+ const [loading, setLoading] = useState(false);
7841
+ useEffect(() => {
7842
+ request("/settings", {
7843
+ method: "GET"
7844
+ }).then((res) => {
7845
+ if (!res?.token) {
7846
+ setShowRegister(true);
7847
+ setShowLogin(false);
7848
+ }
7849
+ });
7850
+ }, []);
7526
7851
  const handleTabChange = (tab) => {
7852
+ if (tab === "api_key") {
7853
+ setShowLogin(true);
7854
+ setShowRegister(false);
7855
+ return;
7856
+ }
7527
7857
  setActiveTab(tab);
7528
7858
  };
7529
- return /* @__PURE__ */ jsx(Box, { padding: 8, children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardBody, { children: /* @__PURE__ */ jsx(CardContent, { width: "100%", children: /* @__PURE__ */ jsx(
7530
- SettingsTabs,
7531
- {
7532
- tabs: [
7533
- { name: "Monitors", value: "monitors" },
7534
- { name: "Notification Channels", value: "notification_channels" },
7535
- { name: "API Key", value: "api_key" }
7536
- ],
7537
- activeTab,
7538
- onTabChange: handleTabChange
7859
+ const logOut = async () => {
7860
+ setLoading(true);
7861
+ const result = await handleLogout();
7862
+ if (result) {
7863
+ toast.success("Logged out successfully.");
7864
+ setLoading(false);
7865
+ setShowLogin(true);
7866
+ return;
7539
7867
  }
7540
- ) }) }) }) });
7868
+ setLoading(false);
7869
+ toast.error("Not able to log out, please try again.");
7870
+ return;
7871
+ };
7872
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7873
+ showExpiredMessage && /* @__PURE__ */ jsx(Box, { margin: 2, children: /* @__PURE__ */ jsx(Alert, { closeLabel: "Close", title: "", variant: "danger", children: showExpiredMessage.charAt(0).toUpperCase() + showExpiredMessage.slice(1) }) }),
7874
+ showLogin && /* @__PURE__ */ jsx(LogInForm, { setShowLoginForm: setShowLogin, setShowRegisterForm: setShowRegister, setShowExpiredMessage }),
7875
+ showRegister && /* @__PURE__ */ jsx(RegisterForm, { setShowRegisterForm: setShowRegister, setShowLoginForm: setShowLogin, setShowExpiredMessage }),
7876
+ !showLogin && !showRegister && /* @__PURE__ */ jsxs(Fragment, { children: [
7877
+ /* @__PURE__ */ jsx(Box, { width: "100%", paddingRight: 8, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "end", children: /* @__PURE__ */ jsx(Button, { onClick: logOut, loading, children: "Log out" }) }) }),
7878
+ /* @__PURE__ */ jsx(
7879
+ SettingsTabs,
7880
+ {
7881
+ tabs: [
7882
+ { name: "Monitors", value: "monitors" },
7883
+ { name: "Notification Channels", value: "notification_channels" }
7884
+ ],
7885
+ activeTab,
7886
+ onTabChange: handleTabChange
7887
+ }
7888
+ )
7889
+ ] })
7890
+ ] });
7541
7891
  }
7542
7892
  const HistogramContainer = styled(Box)`
7543
7893
  display: flex;
@@ -8364,7 +8714,7 @@ function Dashboard() {
8364
8714
  for (let attempt = 0; attempt < retries; attempt++) {
8365
8715
  try {
8366
8716
  const res = await request(`/monitor/${monitorId}`, { method: "GET" });
8367
- if (res?.monitor?.message === "Invalid authentication token") {
8717
+ if (res?.monitor?.message === "Invalid authentication token" || res?.monitor?.status === "error") {
8368
8718
  navigate("/plugins/upsnap/settings");
8369
8719
  return null;
8370
8720
  }
@@ -8850,6 +9200,7 @@ const RegionResponseTimeChart = ({
8850
9200
  function Reachability() {
8851
9201
  const [data, setData] = useState(null);
8852
9202
  const [loading, setLoading] = useState(true);
9203
+ const [refreshing, setRefreshing] = useState(false);
8853
9204
  const [selectedMonitor, setSelectedMonitor] = useState(null);
8854
9205
  const [regionId, setRegionId] = useState(null);
8855
9206
  const [regionResponseTimeData, setRegionResponseTimeData] = useState({});
@@ -8885,27 +9236,37 @@ function Reachability() {
8885
9236
  }
8886
9237
  }
8887
9238
  };
8888
- useEffect(() => {
9239
+ const fetchMonitorDetails = async () => {
8889
9240
  if (monitorId) {
8890
9241
  setLoading(true);
8891
- request(`/monitor/${monitorId}`, { method: "GET" }).then((res) => {
9242
+ try {
9243
+ const res = await request(`/monitor/${monitorId}`, { method: "GET" });
8892
9244
  if (res?.monitor?.message === "Invalid authentication token") {
8893
9245
  setSelectedMonitor(null);
8894
9246
  navigate("/plugins/upsnap/settings");
9247
+ } else {
9248
+ const monitorData = res.monitor?.data || null;
9249
+ setSelectedMonitor(monitorData);
9250
+ if (monitorData?.monitor?.regions) {
9251
+ await fetchResponseTimeDataForRegions(
9252
+ monitorData.monitor.regions,
9253
+ responseTimeRange || "last_24_hours"
9254
+ );
9255
+ }
8895
9256
  }
8896
- setSelectedMonitor(res.monitor?.data || null);
8897
- if (res.monitor?.data?.monitor?.regions) {
8898
- fetchResponseTimeDataForRegions(
8899
- res.monitor.data.monitor.regions,
8900
- responseTimeRange || "last_24_hours"
8901
- );
8902
- }
9257
+ } catch (error) {
9258
+ console.error("Error fetching monitor details:", error);
9259
+ } finally {
8903
9260
  setLoading(false);
8904
- });
9261
+ }
8905
9262
  }
9263
+ };
9264
+ useEffect(() => {
9265
+ fetchMonitorDetails();
8906
9266
  }, [monitorId]);
8907
- const getReachabilityData = async (url, region) => {
8908
- setLoading(true);
9267
+ const getReachabilityData = async (url) => {
9268
+ const stateSetter = loading ? setLoading : setRefreshing;
9269
+ stateSetter(true);
8909
9270
  try {
8910
9271
  const res = await request("/monitor/health-check/uptime", {
8911
9272
  method: "POST",
@@ -8915,7 +9276,7 @@ function Reachability() {
8915
9276
  } catch (err) {
8916
9277
  setData(null);
8917
9278
  } finally {
8918
- setLoading(false);
9279
+ stateSetter(false);
8919
9280
  }
8920
9281
  };
8921
9282
  const fetchResponseTimeForRegion = async (regionId2, start, end) => {
@@ -8933,7 +9294,7 @@ function Reachability() {
8933
9294
  if (selectedMonitor) {
8934
9295
  const primaryRegion = selectedMonitor?.monitor?.regions?.find((r) => r.is_primary);
8935
9296
  setRegionId(primaryRegion?.id || null);
8936
- getReachabilityData(selectedMonitor?.monitor?.config?.meta?.url, primaryRegion?.id || null);
9297
+ getReachabilityData(selectedMonitor?.monitor?.config?.meta?.url);
8937
9298
  }
8938
9299
  }, [selectedMonitor]);
8939
9300
  useEffect(() => {
@@ -8965,6 +9326,11 @@ function Reachability() {
8965
9326
  fetchResponseTimeDataForRegions(selectedMonitor.monitor.regions, String(range) || "last_24_hours");
8966
9327
  }
8967
9328
  };
9329
+ const handleRefresh = async () => {
9330
+ if (selectedMonitor) {
9331
+ await getReachabilityData(selectedMonitor.monitor.config.meta.url);
9332
+ }
9333
+ };
8968
9334
  const regionNames = useMemo(() => {
8969
9335
  const names = {};
8970
9336
  if (selectedMonitor?.monitor?.regions && Array.isArray(selectedMonitor?.monitor?.regions)) {
@@ -8981,11 +9347,15 @@ function Reachability() {
8981
9347
  const tls = meta?.tls;
8982
9348
  const regions = selectedMonitor?.monitor?.regions || [];
8983
9349
  return /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsxs(Box, { padding: 4, children: [
8984
- /* @__PURE__ */ jsx(Box, { marginBottom: 3, children: /* @__PURE__ */ jsxs(Typography, { variant: "beta", children: [
8985
- "Reachability (",
8986
- /* @__PURE__ */ jsx(Link$1, { href: selectedMonitor?.monitor?.config?.meta?.url, isExternal: true, children: selectedMonitor.monitor?.name || "" }),
8987
- ")"
8988
- ] }) }),
9350
+ /* @__PURE__ */ jsx(
9351
+ PageHeader,
9352
+ {
9353
+ title: "Reachability",
9354
+ monitorUrl: selectedMonitor.monitor?.config?.meta?.url,
9355
+ onRefresh: handleRefresh,
9356
+ refreshing
9357
+ }
9358
+ ),
8989
9359
  /* @__PURE__ */ jsx(
8990
9360
  StatusCard,
8991
9361
  {
@@ -38,7 +38,7 @@ const index = {
38
38
  defaultMessage: PLUGIN_ID.slice(0, 1).toUpperCase() + PLUGIN_ID.slice(1)
39
39
  },
40
40
  Component: async () => {
41
- const { App } = await Promise.resolve().then(() => require("./App-Bo_F3q6I.js"));
41
+ const { App } = await Promise.resolve().then(() => require("./App-BWxGckE8.js"));
42
42
  return App;
43
43
  }
44
44
  });