@pfm-platform/alerts-ui-mui 0.1.1 → 0.2.0

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.
package/dist/index.cjs CHANGED
@@ -518,11 +518,739 @@ function AlertDeleteButton({
518
518
  ] })
519
519
  ] });
520
520
  }
521
+ var ICON_OPTIONS = [
522
+ { name: "Notifications", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Notifications, {}), label: "Notifications" },
523
+ { name: "AccountBalance", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.AccountBalance, {}), label: "Account Balance" },
524
+ { name: "AccountBalanceWallet", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.AccountBalanceWallet, {}), label: "Wallet" },
525
+ { name: "TrendingUp", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingUp, {}), label: "Goal" },
526
+ { name: "Receipt", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Receipt, {}), label: "Transaction" },
527
+ { name: "Warning", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Warning, {}), label: "Warning" },
528
+ { name: "Info", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Info, {}), label: "Info" },
529
+ { name: "Error", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Error, {}), label: "Error" },
530
+ { name: "CheckCircle", icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.CheckCircle, {}), label: "Success" }
531
+ ];
532
+ function AlertTypeIcon({ value, onChange, label = "Select Icon" }) {
533
+ const handleIconClick = (iconName) => {
534
+ if (onChange) {
535
+ onChange(iconName);
536
+ }
537
+ };
538
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
539
+ label && /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: label }),
540
+ /* @__PURE__ */ jsxRuntime.jsx(
541
+ material.Box,
542
+ {
543
+ sx: {
544
+ display: "grid",
545
+ gridTemplateColumns: {
546
+ xs: "repeat(3, 1fr)",
547
+ sm: "repeat(4, 1fr)",
548
+ md: "repeat(6, 1fr)"
549
+ },
550
+ gap: 1
551
+ },
552
+ children: ICON_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
553
+ material.IconButton,
554
+ {
555
+ onClick: () => handleIconClick(option.name),
556
+ "aria-label": `Select ${option.label} icon`,
557
+ "aria-pressed": value === option.name,
558
+ sx: {
559
+ border: 1,
560
+ borderColor: value === option.name ? "primary.main" : "divider",
561
+ backgroundColor: value === option.name ? "primary.main" : "background.paper",
562
+ color: value === option.name ? "primary.contrastText" : "text.primary",
563
+ borderRadius: 1,
564
+ "&:hover": {
565
+ backgroundColor: value === option.name ? "primary.dark" : "action.hover",
566
+ boxShadow: 2
567
+ },
568
+ transition: "all 0.2s"
569
+ },
570
+ children: option.icon
571
+ },
572
+ option.name
573
+ ))
574
+ }
575
+ )
576
+ ] });
577
+ }
578
+ function AlertDestinationsForm({
579
+ value = {},
580
+ onChange,
581
+ label = "Alert Destinations"
582
+ }) {
583
+ const [emailEnabled, setEmailEnabled] = react.useState(Boolean(value?.email));
584
+ const [smsEnabled, setSmsEnabled] = react.useState(Boolean(value?.sms));
585
+ const [pushEnabled, setPushEnabled] = react.useState(Boolean(value?.push));
586
+ const [emailInput, setEmailInput] = react.useState(value?.email?.join(", ") || "");
587
+ const [smsInput, setSmsInput] = react.useState(value?.sms?.join(", ") || "");
588
+ const [pushInput, setPushInput] = react.useState(value?.push?.join(", ") || "");
589
+ react.useEffect(() => {
590
+ const newEmail = value?.email?.join(", ") || "";
591
+ const newSms = value?.sms?.join(", ") || "";
592
+ const newPush = value?.push?.join(", ") || "";
593
+ setEmailInput(newEmail);
594
+ setSmsInput(newSms);
595
+ setPushInput(newPush);
596
+ setEmailEnabled(Boolean(value?.email));
597
+ setSmsEnabled(Boolean(value?.sms));
598
+ setPushEnabled(Boolean(value?.push));
599
+ }, [value?.email, value?.sms, value?.push]);
600
+ const [emailError, setEmailError] = react.useState(null);
601
+ const [smsError, setSmsError] = react.useState(null);
602
+ const [pushError, setPushError] = react.useState(null);
603
+ const validateEmail = (email) => {
604
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
605
+ return emailRegex.test(email.trim());
606
+ };
607
+ const validatePhone = (phone) => {
608
+ const phoneRegex = /^\+?[\d\s-()]+$/;
609
+ return phoneRegex.test(phone.trim()) && phone.replace(/\D/g, "").length >= 10;
610
+ };
611
+ const validatePushToken = (token) => {
612
+ return token.trim().length > 0;
613
+ };
614
+ const buildDestinations = (emailVal, smsVal, pushVal, emailEn, smsEn, pushEn) => {
615
+ return {
616
+ email: emailEn && emailVal.trim() ? emailVal.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
617
+ sms: smsEn && smsVal.trim() ? smsVal.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
618
+ push: pushEn && pushVal.trim() ? pushVal.split(",").map((p) => p.trim()).filter(Boolean) : void 0
619
+ };
620
+ };
621
+ const handleEmailChange = (inputValue) => {
622
+ setEmailInput(inputValue);
623
+ setEmailError(null);
624
+ if (inputValue.trim()) {
625
+ const emails = inputValue.split(",").map((e) => e.trim()).filter(Boolean);
626
+ const invalidEmails = emails.filter((e) => !validateEmail(e));
627
+ if (invalidEmails.length > 0) {
628
+ setEmailError(`Invalid email(s): ${invalidEmails.join(", ")}`);
629
+ }
630
+ }
631
+ if (onChange) {
632
+ const destinations = buildDestinations(inputValue, smsInput, pushInput, emailEnabled, smsEnabled, pushEnabled);
633
+ onChange(destinations);
634
+ }
635
+ };
636
+ const handleSmsChange = (inputValue) => {
637
+ setSmsInput(inputValue);
638
+ setSmsError(null);
639
+ if (inputValue.trim()) {
640
+ const phones = inputValue.split(",").map((p) => p.trim()).filter(Boolean);
641
+ const invalidPhones = phones.filter((p) => !validatePhone(p));
642
+ if (invalidPhones.length > 0) {
643
+ setSmsError(`Invalid phone(s): ${invalidPhones.join(", ")}`);
644
+ }
645
+ }
646
+ if (onChange) {
647
+ const destinations = buildDestinations(emailInput, inputValue, pushInput, emailEnabled, smsEnabled, pushEnabled);
648
+ onChange(destinations);
649
+ }
650
+ };
651
+ const handlePushChange = (inputValue) => {
652
+ setPushInput(inputValue);
653
+ setPushError(null);
654
+ if (inputValue.trim()) {
655
+ const tokens = inputValue.split(",").map((t) => t.trim()).filter(Boolean);
656
+ const invalidTokens = tokens.filter((t) => !validatePushToken(t));
657
+ if (invalidTokens.length > 0) {
658
+ setPushError("All push tokens must be non-empty");
659
+ }
660
+ }
661
+ if (onChange) {
662
+ const destinations = buildDestinations(emailInput, smsInput, inputValue, emailEnabled, smsEnabled, pushEnabled);
663
+ onChange(destinations);
664
+ }
665
+ };
666
+ const handleEmailEnabledChange = (enabled) => {
667
+ setEmailEnabled(enabled);
668
+ setEmailError(null);
669
+ if (onChange) {
670
+ const destinations = buildDestinations(emailInput, smsInput, pushInput, enabled, smsEnabled, pushEnabled);
671
+ onChange(destinations);
672
+ }
673
+ };
674
+ const handleSmsEnabledChange = (enabled) => {
675
+ setSmsEnabled(enabled);
676
+ setSmsError(null);
677
+ if (onChange) {
678
+ const destinations = buildDestinations(emailInput, smsInput, pushInput, emailEnabled, enabled, pushEnabled);
679
+ onChange(destinations);
680
+ }
681
+ };
682
+ const handlePushEnabledChange = (enabled) => {
683
+ setPushEnabled(enabled);
684
+ setPushError(null);
685
+ if (onChange) {
686
+ const destinations = buildDestinations(emailInput, smsInput, pushInput, emailEnabled, smsEnabled, enabled);
687
+ onChange(destinations);
688
+ }
689
+ };
690
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
691
+ label && /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mb: 2 }, children: label }),
692
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", flexDirection: "column", gap: 2 }, children: [
693
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
694
+ /* @__PURE__ */ jsxRuntime.jsx(
695
+ material.FormControlLabel,
696
+ {
697
+ control: /* @__PURE__ */ jsxRuntime.jsx(
698
+ material.Checkbox,
699
+ {
700
+ checked: emailEnabled,
701
+ onChange: (e) => handleEmailEnabledChange(e.target.checked),
702
+ "aria-label": "Enable email notifications"
703
+ }
704
+ ),
705
+ label: "Email Notifications"
706
+ }
707
+ ),
708
+ emailEnabled && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(
709
+ material.TextField,
710
+ {
711
+ fullWidth: true,
712
+ label: "Email Addresses",
713
+ placeholder: "email1@example.com, email2@example.com",
714
+ value: emailInput,
715
+ onChange: (e) => handleEmailChange(e.target.value),
716
+ error: Boolean(emailError),
717
+ helperText: emailError || "Separate multiple emails with commas",
718
+ inputProps: {
719
+ "aria-label": "Email addresses"
720
+ }
721
+ }
722
+ ) })
723
+ ] }),
724
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
725
+ /* @__PURE__ */ jsxRuntime.jsx(
726
+ material.FormControlLabel,
727
+ {
728
+ control: /* @__PURE__ */ jsxRuntime.jsx(
729
+ material.Checkbox,
730
+ {
731
+ checked: smsEnabled,
732
+ onChange: (e) => handleSmsEnabledChange(e.target.checked),
733
+ "aria-label": "Enable SMS notifications"
734
+ }
735
+ ),
736
+ label: "SMS Notifications"
737
+ }
738
+ ),
739
+ smsEnabled && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(
740
+ material.TextField,
741
+ {
742
+ fullWidth: true,
743
+ label: "Phone Numbers",
744
+ placeholder: "+1234567890, +0987654321",
745
+ value: smsInput,
746
+ onChange: (e) => handleSmsChange(e.target.value),
747
+ error: Boolean(smsError),
748
+ helperText: smsError || "Separate multiple phone numbers with commas",
749
+ inputProps: {
750
+ "aria-label": "Phone numbers"
751
+ }
752
+ }
753
+ ) })
754
+ ] }),
755
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
756
+ /* @__PURE__ */ jsxRuntime.jsx(
757
+ material.FormControlLabel,
758
+ {
759
+ control: /* @__PURE__ */ jsxRuntime.jsx(
760
+ material.Checkbox,
761
+ {
762
+ checked: pushEnabled,
763
+ onChange: (e) => handlePushEnabledChange(e.target.checked),
764
+ "aria-label": "Enable push notifications"
765
+ }
766
+ ),
767
+ label: "Push Notifications"
768
+ }
769
+ ),
770
+ pushEnabled && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(
771
+ material.TextField,
772
+ {
773
+ fullWidth: true,
774
+ label: "Push Tokens",
775
+ placeholder: "token1, token2",
776
+ value: pushInput,
777
+ onChange: (e) => handlePushChange(e.target.value),
778
+ error: Boolean(pushError),
779
+ helperText: pushError || "Separate multiple push tokens with commas",
780
+ inputProps: {
781
+ "aria-label": "Push notification tokens"
782
+ }
783
+ }
784
+ ) })
785
+ ] }),
786
+ !emailEnabled && !smsEnabled && !pushEnabled && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "info", sx: { mt: 1 }, children: "Select at least one notification method to receive alerts" })
787
+ ] })
788
+ ] });
789
+ }
790
+ function AlertDestinationsDialog({
791
+ open,
792
+ onClose,
793
+ onSave,
794
+ initialValue = {},
795
+ title = "Configure Alert Destinations"
796
+ }) {
797
+ const [destinations, setDestinations] = react.useState(initialValue);
798
+ const [hasChanges, setHasChanges] = react.useState(false);
799
+ const handleDestinationsChange = (newDestinations) => {
800
+ setDestinations(newDestinations);
801
+ setHasChanges(true);
802
+ };
803
+ const handleSave = () => {
804
+ onSave(destinations);
805
+ setHasChanges(false);
806
+ onClose();
807
+ };
808
+ const handleCancel = () => {
809
+ setDestinations(initialValue);
810
+ setHasChanges(false);
811
+ onClose();
812
+ };
813
+ const handleClose = (_event, reason) => {
814
+ if (reason === "backdropClick" || reason === "escapeKeyDown") {
815
+ handleCancel();
816
+ }
817
+ };
818
+ const hasAtLeastOneDestination = destinations.email && destinations.email.length > 0 || destinations.sms && destinations.sms.length > 0 || destinations.push && destinations.push.length > 0;
819
+ return /* @__PURE__ */ jsxRuntime.jsxs(
820
+ material.Dialog,
821
+ {
822
+ open,
823
+ onClose: handleClose,
824
+ maxWidth: "sm",
825
+ fullWidth: true,
826
+ "aria-labelledby": "alert-destinations-dialog-title",
827
+ children: [
828
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogTitle, { id: "alert-destinations-dialog-title", children: [
829
+ title,
830
+ /* @__PURE__ */ jsxRuntime.jsx(
831
+ material.IconButton,
832
+ {
833
+ "aria-label": "Close dialog",
834
+ onClick: handleCancel,
835
+ sx: {
836
+ position: "absolute",
837
+ right: 8,
838
+ top: 8
839
+ },
840
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Close, {})
841
+ }
842
+ )
843
+ ] }),
844
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsx(
845
+ AlertDestinationsForm,
846
+ {
847
+ value: destinations,
848
+ onChange: handleDestinationsChange,
849
+ label: ""
850
+ }
851
+ ) }),
852
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { sx: { px: 3, pb: 2 }, children: [
853
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: handleCancel, color: "inherit", children: "Cancel" }),
854
+ /* @__PURE__ */ jsxRuntime.jsx(
855
+ material.Button,
856
+ {
857
+ onClick: handleSave,
858
+ variant: "contained",
859
+ disabled: !hasAtLeastOneDestination,
860
+ "aria-label": "Save destinations",
861
+ children: "Save"
862
+ }
863
+ )
864
+ ] })
865
+ ]
866
+ }
867
+ );
868
+ }
869
+ function AlertActionsDialog({
870
+ open,
871
+ onClose,
872
+ onSave,
873
+ initialValue = [],
874
+ title = "Configure Alert Actions"
875
+ }) {
876
+ const [actions, setActions] = react.useState(initialValue.length > 0 ? initialValue : []);
877
+ const handleAddAction = () => {
878
+ setActions([...actions, { type: "webhook", config: {} }]);
879
+ };
880
+ const handleRemoveAction = (index) => {
881
+ const newActions = actions.filter((_, i) => i !== index);
882
+ setActions(newActions);
883
+ };
884
+ const handleActionTypeChange = (index, type) => {
885
+ const newActions = [...actions];
886
+ newActions[index] = { type, config: {} };
887
+ setActions(newActions);
888
+ };
889
+ const handleConfigChange = (index, key, value) => {
890
+ const newActions = [...actions];
891
+ newActions[index] = {
892
+ ...newActions[index],
893
+ config: {
894
+ ...newActions[index].config,
895
+ [key]: value
896
+ }
897
+ };
898
+ setActions(newActions);
899
+ };
900
+ const handleSave = () => {
901
+ onSave(actions);
902
+ onClose();
903
+ };
904
+ const handleCancel = () => {
905
+ setActions(initialValue.length > 0 ? initialValue : []);
906
+ onClose();
907
+ };
908
+ const handleClose = (_event, reason) => {
909
+ if (reason === "backdropClick" || reason === "escapeKeyDown") {
910
+ handleCancel();
911
+ }
912
+ };
913
+ const getConfigFieldsForType = (type) => {
914
+ switch (type) {
915
+ case "webhook":
916
+ return ["url", "method"];
917
+ case "email":
918
+ return ["to", "subject"];
919
+ case "sms":
920
+ return ["phoneNumber", "message"];
921
+ case "custom":
922
+ return ["command", "args"];
923
+ default:
924
+ return [];
925
+ }
926
+ };
927
+ return /* @__PURE__ */ jsxRuntime.jsxs(
928
+ material.Dialog,
929
+ {
930
+ open,
931
+ onClose: handleClose,
932
+ maxWidth: "md",
933
+ fullWidth: true,
934
+ "aria-labelledby": "alert-actions-dialog-title",
935
+ children: [
936
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogTitle, { id: "alert-actions-dialog-title", children: [
937
+ title,
938
+ /* @__PURE__ */ jsxRuntime.jsx(
939
+ material.IconButton,
940
+ {
941
+ "aria-label": "Close dialog",
942
+ onClick: handleCancel,
943
+ sx: {
944
+ position: "absolute",
945
+ right: 8,
946
+ top: 8
947
+ },
948
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Close, {})
949
+ }
950
+ )
951
+ ] }),
952
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", flexDirection: "column", gap: 3 }, children: [
953
+ actions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", sx: { textAlign: "center", py: 2 }, children: 'No actions configured. Click "Add Action" to get started.' }),
954
+ actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsxs(
955
+ material.Box,
956
+ {
957
+ sx: {
958
+ p: 2,
959
+ border: 1,
960
+ borderColor: "divider",
961
+ borderRadius: 1,
962
+ position: "relative"
963
+ },
964
+ children: [
965
+ /* @__PURE__ */ jsxRuntime.jsx(
966
+ material.IconButton,
967
+ {
968
+ "aria-label": `Remove action ${index + 1}`,
969
+ onClick: () => handleRemoveAction(index),
970
+ size: "small",
971
+ sx: {
972
+ position: "absolute",
973
+ right: 8,
974
+ top: 8
975
+ },
976
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {})
977
+ }
978
+ ),
979
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "subtitle2", sx: { mb: 2 }, children: [
980
+ "Action ",
981
+ index + 1
982
+ ] }),
983
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, sx: { mb: 2 }, children: [
984
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: `action-type-${index}-label`, children: "Action Type" }),
985
+ /* @__PURE__ */ jsxRuntime.jsxs(
986
+ material.Select,
987
+ {
988
+ labelId: `action-type-${index}-label`,
989
+ value: action.type,
990
+ label: "Action Type",
991
+ onChange: (e) => handleActionTypeChange(index, e.target.value),
992
+ inputProps: {
993
+ "aria-label": `Action ${index + 1} type`
994
+ },
995
+ children: [
996
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "webhook", children: "Webhook" }),
997
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "email", children: "Email" }),
998
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "sms", children: "SMS" }),
999
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "custom", children: "Custom" })
1000
+ ]
1001
+ }
1002
+ )
1003
+ ] }),
1004
+ getConfigFieldsForType(action.type).map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1005
+ material.TextField,
1006
+ {
1007
+ fullWidth: true,
1008
+ label: field.charAt(0).toUpperCase() + field.slice(1),
1009
+ value: action.config[field] || "",
1010
+ onChange: (e) => handleConfigChange(index, field, e.target.value),
1011
+ sx: { mb: 2 },
1012
+ inputProps: {
1013
+ "aria-label": `Action ${index + 1} ${field}`
1014
+ }
1015
+ },
1016
+ field
1017
+ ))
1018
+ ]
1019
+ },
1020
+ index
1021
+ )),
1022
+ /* @__PURE__ */ jsxRuntime.jsx(
1023
+ material.Button,
1024
+ {
1025
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Add, {}),
1026
+ onClick: handleAddAction,
1027
+ variant: "outlined",
1028
+ "aria-label": "Add action",
1029
+ children: "Add Action"
1030
+ }
1031
+ )
1032
+ ] }) }),
1033
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { sx: { px: 3, pb: 2 }, children: [
1034
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: handleCancel, color: "inherit", children: "Cancel" }),
1035
+ /* @__PURE__ */ jsxRuntime.jsx(
1036
+ material.Button,
1037
+ {
1038
+ onClick: handleSave,
1039
+ variant: "contained",
1040
+ "aria-label": "Save actions",
1041
+ children: "Save"
1042
+ }
1043
+ )
1044
+ ] })
1045
+ ]
1046
+ }
1047
+ );
1048
+ }
1049
+ function AlertNotificationSettings({
1050
+ value = { enabled: true, frequency: "immediate", groupBy: "none" },
1051
+ onChange,
1052
+ title = "Notification Settings"
1053
+ }) {
1054
+ const [enabled, setEnabled] = react.useState(value.enabled ?? true);
1055
+ const [quietHoursEnabled, setQuietHoursEnabled] = react.useState(value.quietHours?.enabled ?? false);
1056
+ const [quietHoursStart, setQuietHoursStart] = react.useState(value.quietHours?.start ?? "22:00");
1057
+ const [quietHoursEnd, setQuietHoursEnd] = react.useState(value.quietHours?.end ?? "08:00");
1058
+ const [frequency, setFrequency] = react.useState(
1059
+ value.frequency ?? "immediate"
1060
+ );
1061
+ const [groupBy, setGroupBy] = react.useState(value.groupBy ?? "none");
1062
+ const buildSettings = (isEnabled, qhEnabled, qhStart, qhEnd, freq, group) => {
1063
+ return {
1064
+ enabled: isEnabled,
1065
+ quietHours: qhEnabled ? {
1066
+ enabled: qhEnabled,
1067
+ start: qhStart,
1068
+ end: qhEnd
1069
+ } : void 0,
1070
+ frequency: freq,
1071
+ groupBy: group
1072
+ };
1073
+ };
1074
+ const handleEnabledChange = (isEnabled) => {
1075
+ setEnabled(isEnabled);
1076
+ if (onChange) {
1077
+ const settings = buildSettings(
1078
+ isEnabled,
1079
+ quietHoursEnabled,
1080
+ quietHoursStart,
1081
+ quietHoursEnd,
1082
+ frequency,
1083
+ groupBy
1084
+ );
1085
+ onChange(settings);
1086
+ }
1087
+ };
1088
+ const handleQuietHoursEnabledChange = (qhEnabled) => {
1089
+ setQuietHoursEnabled(qhEnabled);
1090
+ if (onChange) {
1091
+ const settings = buildSettings(enabled, qhEnabled, quietHoursStart, quietHoursEnd, frequency, groupBy);
1092
+ onChange(settings);
1093
+ }
1094
+ };
1095
+ const handleQuietHoursStartChange = (start) => {
1096
+ setQuietHoursStart(start);
1097
+ if (onChange) {
1098
+ const settings = buildSettings(enabled, quietHoursEnabled, start, quietHoursEnd, frequency, groupBy);
1099
+ onChange(settings);
1100
+ }
1101
+ };
1102
+ const handleQuietHoursEndChange = (end) => {
1103
+ setQuietHoursEnd(end);
1104
+ if (onChange) {
1105
+ const settings = buildSettings(enabled, quietHoursEnabled, quietHoursStart, end, frequency, groupBy);
1106
+ onChange(settings);
1107
+ }
1108
+ };
1109
+ const handleFrequencyChange = (freq) => {
1110
+ setFrequency(freq);
1111
+ if (onChange) {
1112
+ const settings = buildSettings(enabled, quietHoursEnabled, quietHoursStart, quietHoursEnd, freq, groupBy);
1113
+ onChange(settings);
1114
+ }
1115
+ };
1116
+ const handleGroupByChange = (group) => {
1117
+ setGroupBy(group);
1118
+ if (onChange) {
1119
+ const settings = buildSettings(enabled, quietHoursEnabled, quietHoursStart, quietHoursEnd, frequency, group);
1120
+ onChange(settings);
1121
+ }
1122
+ };
1123
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Paper, { sx: { p: 3 }, children: [
1124
+ title && /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", sx: { mb: 3 }, children: title }),
1125
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", flexDirection: "column", gap: 3 }, children: [
1126
+ /* @__PURE__ */ jsxRuntime.jsx(
1127
+ material.FormControlLabel,
1128
+ {
1129
+ control: /* @__PURE__ */ jsxRuntime.jsx(
1130
+ material.Switch,
1131
+ {
1132
+ checked: enabled,
1133
+ onChange: (e) => handleEnabledChange(e.target.checked),
1134
+ "aria-label": "Enable notifications"
1135
+ }
1136
+ ),
1137
+ label: "Enable Notifications"
1138
+ }
1139
+ ),
1140
+ enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1141
+ /* @__PURE__ */ jsxRuntime.jsx(material.Divider, {}),
1142
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, children: [
1143
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "frequency-label", children: "Notification Frequency" }),
1144
+ /* @__PURE__ */ jsxRuntime.jsxs(
1145
+ material.Select,
1146
+ {
1147
+ labelId: "frequency-label",
1148
+ value: frequency,
1149
+ label: "Notification Frequency",
1150
+ onChange: (e) => handleFrequencyChange(e.target.value),
1151
+ inputProps: {
1152
+ "aria-label": "Notification frequency"
1153
+ },
1154
+ children: [
1155
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "immediate", children: "Immediate" }),
1156
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "hourly", children: "Hourly Digest" }),
1157
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "daily", children: "Daily Digest" }),
1158
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "weekly", children: "Weekly Digest" })
1159
+ ]
1160
+ }
1161
+ )
1162
+ ] }),
1163
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, children: [
1164
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "groupby-label", children: "Group Notifications By" }),
1165
+ /* @__PURE__ */ jsxRuntime.jsxs(
1166
+ material.Select,
1167
+ {
1168
+ labelId: "groupby-label",
1169
+ value: groupBy,
1170
+ label: "Group Notifications By",
1171
+ onChange: (e) => handleGroupByChange(e.target.value),
1172
+ inputProps: {
1173
+ "aria-label": "Group notifications by"
1174
+ },
1175
+ children: [
1176
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "none", children: "None" }),
1177
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "type", children: "Type" }),
1178
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "priority", children: "Priority" })
1179
+ ]
1180
+ }
1181
+ )
1182
+ ] }),
1183
+ /* @__PURE__ */ jsxRuntime.jsx(material.Divider, {}),
1184
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
1185
+ /* @__PURE__ */ jsxRuntime.jsx(
1186
+ material.FormControlLabel,
1187
+ {
1188
+ control: /* @__PURE__ */ jsxRuntime.jsx(
1189
+ material.Switch,
1190
+ {
1191
+ checked: quietHoursEnabled,
1192
+ onChange: (e) => handleQuietHoursEnabledChange(e.target.checked),
1193
+ "aria-label": "Enable quiet hours"
1194
+ }
1195
+ ),
1196
+ label: "Quiet Hours"
1197
+ }
1198
+ ),
1199
+ quietHoursEnabled && /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 2, display: "flex", gap: 2 }, children: [
1200
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { sx: { flex: 1 }, children: [
1201
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "quiet-start-label", children: "Start Time" }),
1202
+ /* @__PURE__ */ jsxRuntime.jsx(
1203
+ material.Select,
1204
+ {
1205
+ labelId: "quiet-start-label",
1206
+ value: quietHoursStart,
1207
+ label: "Start Time",
1208
+ onChange: (e) => handleQuietHoursStartChange(e.target.value),
1209
+ inputProps: {
1210
+ "aria-label": "Quiet hours start time"
1211
+ },
1212
+ children: Array.from({ length: 24 }, (_, i) => {
1213
+ const hour = i.toString().padStart(2, "0");
1214
+ return /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: `${hour}:00`, children: `${hour}:00` }, `${hour}:00`);
1215
+ })
1216
+ }
1217
+ )
1218
+ ] }),
1219
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { sx: { flex: 1 }, children: [
1220
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "quiet-end-label", children: "End Time" }),
1221
+ /* @__PURE__ */ jsxRuntime.jsx(
1222
+ material.Select,
1223
+ {
1224
+ labelId: "quiet-end-label",
1225
+ value: quietHoursEnd,
1226
+ label: "End Time",
1227
+ onChange: (e) => handleQuietHoursEndChange(e.target.value),
1228
+ inputProps: {
1229
+ "aria-label": "Quiet hours end time"
1230
+ },
1231
+ children: Array.from({ length: 24 }, (_, i) => {
1232
+ const hour = i.toString().padStart(2, "0");
1233
+ return /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: `${hour}:00`, children: `${hour}:00` }, `${hour}:00`);
1234
+ })
1235
+ }
1236
+ )
1237
+ ] })
1238
+ ] })
1239
+ ] })
1240
+ ] })
1241
+ ] })
1242
+ ] });
1243
+ }
521
1244
 
1245
+ exports.AlertActionsDialog = AlertActionsDialog;
522
1246
  exports.AlertCreateForm = AlertCreateForm;
523
1247
  exports.AlertDeleteButton = AlertDeleteButton;
1248
+ exports.AlertDestinationsDialog = AlertDestinationsDialog;
1249
+ exports.AlertDestinationsForm = AlertDestinationsForm;
524
1250
  exports.AlertEditForm = AlertEditForm;
525
1251
  exports.AlertList = AlertList;
1252
+ exports.AlertNotificationSettings = AlertNotificationSettings;
526
1253
  exports.AlertSummary = AlertSummary;
1254
+ exports.AlertTypeIcon = AlertTypeIcon;
527
1255
  //# sourceMappingURL=index.cjs.map
528
1256
  //# sourceMappingURL=index.cjs.map