@tellescope/react-components 1.226.0 → 1.227.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.
@@ -72,7 +72,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
72
72
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
73
73
  import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
74
74
  import axios from "axios";
75
- import { Autocomplete, Box, Button, Checkbox, Chip, Divider, FormControl, FormControlLabel, FormLabel, Grid, InputLabel, MenuItem, Radio, RadioGroup, Select, TextField, Typography } from "@mui/material";
75
+ import { Autocomplete, Box, Button, Checkbox, Chip, Collapse, Divider, FormControl, FormControlLabel, FormLabel, Grid, IconButton as MuiIconButton, InputLabel, MenuItem, Radio, RadioGroup, Select, TextField, Typography } from "@mui/material";
76
76
  import { useDropzone } from "react-dropzone";
77
77
  import { CANVAS_TITLE, EMOTII_TITLE, INSURANCE_RELATIONSHIPS, INSURANCE_RELATIONSHIPS_CANVAS, PRIMARY_HEX, RELATIONSHIP_TYPES, TELLESCOPE_GENDERS } from "@tellescope/constants";
78
78
  import { MM_DD_YYYY_to_YYYY_MM_DD, capture_is_supported, downloadFile, emit_gtm_event, first_letter_capitalized, form_response_value_to_string, getLocalTimezone, getPublicFileURL, mm_dd_yyyy, replace_enduser_template_values, truncate_string, update_local_storage, user_display_name } from "@tellescope/utilities";
@@ -82,7 +82,7 @@ import Slider from '@mui/material/Slider';
82
82
  import LinearProgress from '@mui/material/LinearProgress';
83
83
  import DatePicker from "react-datepicker";
84
84
  import { datepickerCSS } from "./css/react-datepicker"; // avoids build issue with RN
85
- import { CancelIcon, IconButton, LabeledIconButton, LoadingButton, form_display_text_for_language, isDateString, useProducts, useResolvedSession } from "..";
85
+ import { CancelIcon, IconButton, LabeledIconButton, LoadingButton, form_display_text_for_language, isDateString, useResolvedSession } from "..";
86
86
  import { css } from '@emotion/css';
87
87
  import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
88
88
  import DragIndicatorIcon from '@mui/icons-material/DragIndicator';
@@ -91,7 +91,7 @@ import AddPhotoAlternateIcon from '@mui/icons-material/AddPhotoAlternate';
91
91
  import LanguageIcon from '@mui/icons-material/Language';
92
92
  import { Elements, PaymentElement, useStripe, useElements, EmbeddedCheckout, EmbeddedCheckoutProvider } from '@stripe/react-stripe-js';
93
93
  import { loadStripe } from '@stripe/stripe-js';
94
- import { CheckCircleOutline, Delete, Edit } from "@mui/icons-material";
94
+ import { CheckCircleOutline, Delete, Edit, ExpandMore } from "@mui/icons-material";
95
95
  import { WYSIWYG } from "./wysiwyg";
96
96
  export var LanguageSelect = function (_a) {
97
97
  var value = _a.value, props = __rest(_a, ["value"]);
@@ -740,23 +740,60 @@ export var MultipleChoiceInput = function (_a) {
740
740
  var _b;
741
741
  var field = _a.field, form = _a.form, _value = _a.value, onChange = _a.onChange;
742
742
  var value = typeof _value === 'string' ? [_value] : _value; // if loading existingResponses, allows them to be a string
743
- var _d = field.options, choices = _d.choices, radio = _d.radio, other = _d.other;
743
+ var _d = field.options, choices = _d.choices, radio = _d.radio, other = _d.other, optionDetails = _d.optionDetails;
744
+ var _e = useState({}), expandedDescriptions = _e[0], setExpandedDescriptions = _e[1];
744
745
  // current other string
745
746
  var enteringOtherStringRef = React.useRef(''); // if typing otherString as prefix of a checkbox value, don't auto-select
746
747
  var otherString = (_b = value === null || value === void 0 ? void 0 : value.find(function (v) { var _a; return v === enteringOtherStringRef.current || !((_a = (choices !== null && choices !== void 0 ? choices : [])) === null || _a === void 0 ? void 0 : _a.find(function (c) { return c === v; })); })) !== null && _b !== void 0 ? _b : '';
748
+ var getDescriptionForChoice = useCallback(function (choice) {
749
+ var _a;
750
+ return (_a = optionDetails === null || optionDetails === void 0 ? void 0 : optionDetails.find(function (detail) { return detail.option === choice; })) === null || _a === void 0 ? void 0 : _a.description;
751
+ }, [optionDetails]);
752
+ var toggleDescription = useCallback(function (index) {
753
+ setExpandedDescriptions(function (prev) {
754
+ var _a;
755
+ return (__assign(__assign({}, prev), (_a = {}, _a[index] = !prev[index], _a)));
756
+ });
757
+ }, []);
747
758
  return (_jsxs(Grid, __assign({ container: true, alignItems: "center" }, { children: [radio
748
759
  ? (_jsxs(FormControl, __assign({ fullWidth: true }, { children: [_jsx(FormLabel, __assign({ id: "radio-group-".concat(field.id, "-label") }, { children: form_display_text_for_language(form, "Select One") })), _jsx(RadioGroup, __assign({ "aria-labelledby": "radio-group-".concat(field.id, "-label"), defaultValue: "female", name: "radio-group-".concat(field.id) }, { children: (choices !== null && choices !== void 0 ? choices : []).map(function (c, i) {
749
- return _jsx(FormControlLabel, { color: "primary", label: c, sx: multipleChoiceItemSx, style: { marginLeft: '0px' }, checked: !!(value === null || value === void 0 ? void 0 : value.includes(c)) && c !== otherString, control: _jsx(Radio, { onClick: function () { return onChange((value === null || value === void 0 ? void 0 : value.includes(c)) ? [] : [c], field.id); } }) }, i);
750
- }) }))] }))) : ((choices !== null && choices !== void 0 ? choices : []).map(function (c, i) { return (_jsx(Grid, __assign({ xs: 12, onClick: function () {
751
- var _a, _b, _d, _e;
752
- return onChange(((value === null || value === void 0 ? void 0 : value.includes(c))
753
- ? ((radio || ((_b = (_a = field.options) === null || _a === void 0 ? void 0 : _a.radioChoices) === null || _b === void 0 ? void 0 : _b.includes(c)))
754
- ? []
755
- : value.filter(function (v) { return v !== c; }))
756
- : ((radio || ((_e = (_d = field.options) === null || _d === void 0 ? void 0 : _d.radioChoices) === null || _e === void 0 ? void 0 : _e.includes(c)))
757
- ? [c]
758
- : __spreadArray(__spreadArray([], (value !== null && value !== void 0 ? value : []).filter(function (x) { var _a, _b; return !((_b = (_a = field.options) === null || _a === void 0 ? void 0 : _a.radioChoices) === null || _b === void 0 ? void 0 : _b.includes(x)); }), true), [c], false))), field.id);
759
- } }, { children: _jsxs(Grid, __assign({ container: true, alignItems: "center", wrap: "nowrap", sx: multipleChoiceItemSx }, { children: [_jsx(Checkbox, { color: "primary", checked: !!(value === null || value === void 0 ? void 0 : value.includes(c)) && c !== otherString, inputProps: { 'aria-label': 'primary checkbox' } }), _jsxs(Typography, __assign({ component: "span" }, { children: [" ", c, " "] }))] })) }), i)); })), other &&
760
+ var description = getDescriptionForChoice(c);
761
+ var hasDescription = !!description;
762
+ var isExpanded = expandedDescriptions[i];
763
+ return (_jsxs(Box, __assign({ sx: { width: '100%' } }, { children: [_jsx(Box, __assign({ sx: { display: 'flex', alignItems: 'center', width: '100%' } }, { children: _jsx(FormControlLabel, { sx: __assign(__assign({}, multipleChoiceItemSx), { flex: 1, marginLeft: '0px' }), checked: !!(value === null || value === void 0 ? void 0 : value.includes(c)) && c !== otherString, control: _jsx(Radio, { onClick: function () { return onChange((value === null || value === void 0 ? void 0 : value.includes(c)) ? [] : [c], field.id); } }), label: _jsxs(Box, __assign({ sx: { display: 'flex', alignItems: 'center', width: '100%' } }, { children: [_jsx(Typography, __assign({ component: "span", sx: { flex: 1 } }, { children: c })), hasDescription && (_jsx(MuiIconButton, __assign({ size: "small", onClick: function (e) {
764
+ e.stopPropagation();
765
+ toggleDescription(i);
766
+ }, sx: {
767
+ transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',
768
+ transition: 'transform 0.2s',
769
+ ml: 1
770
+ } }, { children: _jsx(ExpandMore, { fontSize: "small" }) })))] })) }) })), hasDescription && (_jsx(Collapse, __assign({ in: isExpanded }, { children: _jsx(Box, __assign({ sx: { pl: '42px', pr: 2, pb: 1 } }, { children: _jsx(Typography, __assign({ variant: "body2", color: "text.secondary" }, { children: description })) })) })))] }), i));
771
+ }) }))] }))) : ((choices !== null && choices !== void 0 ? choices : []).map(function (c, i) {
772
+ var description = getDescriptionForChoice(c);
773
+ var hasDescription = !!description;
774
+ var isExpanded = expandedDescriptions[i];
775
+ return (_jsx(Grid, __assign({ xs: 12 }, { children: _jsxs(Box, __assign({ sx: { width: '100%' } }, { children: [_jsxs(Box, __assign({ sx: __assign(__assign({}, multipleChoiceItemSx), { display: 'flex', alignItems: 'center', cursor: 'pointer', width: '100%' }), onClick: function (e) {
776
+ var _a, _b, _d, _e;
777
+ // Don't trigger selection if clicking on the expand button
778
+ if (e.target.closest('.expand-button')) {
779
+ return;
780
+ }
781
+ onChange(((value === null || value === void 0 ? void 0 : value.includes(c))
782
+ ? ((radio || ((_b = (_a = field.options) === null || _a === void 0 ? void 0 : _a.radioChoices) === null || _b === void 0 ? void 0 : _b.includes(c)))
783
+ ? []
784
+ : value.filter(function (v) { return v !== c; }))
785
+ : ((radio || ((_e = (_d = field.options) === null || _d === void 0 ? void 0 : _d.radioChoices) === null || _e === void 0 ? void 0 : _e.includes(c)))
786
+ ? [c]
787
+ : __spreadArray(__spreadArray([], (value !== null && value !== void 0 ? value : []).filter(function (x) { var _a, _b; return !((_b = (_a = field.options) === null || _a === void 0 ? void 0 : _a.radioChoices) === null || _b === void 0 ? void 0 : _b.includes(x)); }), true), [c], false))), field.id);
788
+ } }, { children: [_jsx(Checkbox, { color: "primary", checked: !!(value === null || value === void 0 ? void 0 : value.includes(c)) && c !== otherString, inputProps: { 'aria-label': 'primary checkbox' } }), _jsx(Typography, __assign({ component: "span", sx: { flex: 1 } }, { children: c })), hasDescription && (_jsx(MuiIconButton, __assign({ className: "expand-button", size: "small", onClick: function (e) {
789
+ e.stopPropagation();
790
+ toggleDescription(i);
791
+ }, sx: {
792
+ transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',
793
+ transition: 'transform 0.2s',
794
+ ml: 1
795
+ } }, { children: _jsx(ExpandMore, { fontSize: "small" }) })))] })), hasDescription && (_jsx(Collapse, __assign({ in: isExpanded }, { children: _jsx(Box, __assign({ sx: { pl: '42px', pr: 2, pb: 1 } }, { children: _jsx(Typography, __assign({ variant: "body2", color: "text.secondary" }, { children: description })) })) })))] })) }), i));
796
+ })), other &&
760
797
  _jsx(Grid, __assign({ item: true, xs: 12 }, { children: _jsx(TextField // className={classes.textField}
761
798
  , { InputProps: { sx: { borderRadius: 2.5 } }, sx: { width: radio ? "calc(100% - 15px)" : '100%' }, size: "small", "aria-label": form_display_text_for_language(form, "Other"), value: otherString, placeholder: form_display_text_for_language(form, "Other"), variant: "outlined",
762
799
  // onClick={() => !otherChecked && handleOtherChecked()} // allow click to enable when disabled
@@ -779,17 +816,48 @@ export var StripeInput = function (_a) {
779
816
  var _f = useState(''), businessName = _f[0], setBusinessName = _f[1];
780
817
  var _g = useState(false), isCheckout = _g[0], setIsCheckout = _g[1];
781
818
  var _h = useState(), stripePromise = _h[0], setStripePromise = _h[1];
782
- var _j = useProducts({ dontFetch: true }), findProduct = _j[1].findById;
783
- var _k = useState(''), answertext = _k[0], setAnswertext = _k[1];
784
- var _l = useState(''), error = _l[0], setError = _l[1];
819
+ var _j = useState(''), answertext = _j[0], setAnswertext = _j[1];
820
+ var _k = useState(''), error = _k[0], setError = _k[1];
821
+ var _l = useState([]), selectedProducts = _l[0], setSelectedProducts = _l[1];
822
+ var _m = useState(false), showProductSelection = _m[0], setShowProductSelection = _m[1];
823
+ var _o = useState([]), availableProducts = _o[0], setAvailableProducts = _o[1];
824
+ var _p = useState(false), loadingProducts = _p[0], setLoadingProducts = _p[1];
785
825
  var fetchRef = useRef(false);
786
826
  useEffect(function () {
787
- var _a;
827
+ var _a, _b, _d;
788
828
  if (fetchRef.current)
789
829
  return;
790
830
  if (value && ((_a = session.userInfo) === null || _a === void 0 ? void 0 : _a.stripeCustomerId)) {
791
831
  return setCustomerId(function (c) { var _a; return c ? c : (_a = session.userInfo) === null || _a === void 0 ? void 0 : _a.stripeCustomerId; }); // already paid or saved card
792
832
  }
833
+ // Check if product selection mode is enabled
834
+ if (((_b = field.options) === null || _b === void 0 ? void 0 : _b.stripeProductSelectionMode) && (((_d = field.options) === null || _d === void 0 ? void 0 : _d.productIds) || []).length > 1) {
835
+ setShowProductSelection(true);
836
+ setLoadingProducts(true);
837
+ // Fetch product data with real-time Stripe pricing via proxy_read
838
+ var productIds = (field.options.productIds || []).join(',');
839
+ session.api.integrations.proxy_read({
840
+ integration: 'Stripe',
841
+ type: 'product-prices',
842
+ id: productIds,
843
+ query: field.options.stripeKey
844
+ })
845
+ .then(function (_a) {
846
+ var data = _a.data;
847
+ setAvailableProducts(data.products || []);
848
+ setLoadingProducts(false);
849
+ })
850
+ .catch(function (e) {
851
+ var _a, _b;
852
+ console.error('Error loading product data:', e);
853
+ var errorMessage = ((_b = (_a = e === null || e === void 0 ? void 0 : e.message) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, 'Stripe pricing error:'))
854
+ ? e.message.replace('Stripe pricing error: ', '')
855
+ : 'Failed to load product information from Stripe';
856
+ setError("Product configuration error: ".concat(errorMessage));
857
+ setLoadingProducts(false);
858
+ });
859
+ return;
860
+ }
793
861
  fetchRef.current = true;
794
862
  session.api.form_responses.stripe_details({ fieldId: field.id, enduserId: enduserId })
795
863
  .then(function (_a) {
@@ -808,8 +876,71 @@ export var StripeInput = function (_a) {
808
876
  }
809
877
  });
810
878
  }, [session, value, field.id, enduserId]);
811
- var cost = ((((_b = field.options) === null || _b === void 0 ? void 0 : _b.productIds) || []).map(function (id) { return findProduct(id, { batch: false }); }) // seems to be having issues with bulk read
812
- .reduce(function (t, p) { var _a; return t + (((_a = p === null || p === void 0 ? void 0 : p.cost) === null || _a === void 0 ? void 0 : _a.amount) || 0); }, 0));
879
+ var cost = (showProductSelection
880
+ ? selectedProducts.reduce(function (total, productId) {
881
+ var _a;
882
+ var product = availableProducts.find(function (p) { return p._id === productId; });
883
+ if (product === null || product === void 0 ? void 0 : product.currentPrice) {
884
+ return total + (product.currentPrice.amount || 0);
885
+ }
886
+ return total + (((_a = product === null || product === void 0 ? void 0 : product.cost) === null || _a === void 0 ? void 0 : _a.amount) || 0);
887
+ }, 0)
888
+ : 0 // Will be calculated by existing Stripe flow when not in selection mode
889
+ );
890
+ // Handle product selection step
891
+ if (showProductSelection) {
892
+ if (error) {
893
+ return (_jsxs(Grid, __assign({ container: true, direction: "column", spacing: 2, alignItems: "center" }, { children: [_jsx(Grid, __assign({ item: true }, { children: _jsx(Typography, __assign({ color: "error", variant: "h6" }, { children: "Product Configuration Error" })) })), _jsx(Grid, __assign({ item: true }, { children: _jsx(Typography, __assign({ color: "error", sx: { textAlign: 'center' } }, { children: error })) }))] })));
894
+ }
895
+ if (loadingProducts) {
896
+ return (_jsxs(Grid, __assign({ container: true, direction: "column", spacing: 2, alignItems: "center" }, { children: [_jsx(Grid, __assign({ item: true }, { children: _jsx(LinearProgress, {}) })), _jsx(Grid, __assign({ item: true }, { children: _jsx(Typography, { children: "Loading product information..." }) }))] })));
897
+ }
898
+ var isSingleSelection_1 = ((_b = field.options) === null || _b === void 0 ? void 0 : _b.radio) === true;
899
+ var handleProductSelection_1 = function (productId) {
900
+ if (isSingleSelection_1) {
901
+ setSelectedProducts([productId]);
902
+ }
903
+ else {
904
+ setSelectedProducts(function (prev) {
905
+ return prev.includes(productId)
906
+ ? prev.filter(function (id) { return id !== productId; })
907
+ : __spreadArray(__spreadArray([], prev, true), [productId], false);
908
+ });
909
+ }
910
+ };
911
+ var handleContinueToPayment = function () {
912
+ if (selectedProducts.length === 0)
913
+ return;
914
+ setShowProductSelection(false);
915
+ fetchRef.current = true;
916
+ // Now fetch Stripe details with selected products
917
+ session.api.form_responses.stripe_details(__assign({ fieldId: field.id, enduserId: enduserId }, (selectedProducts.length > 0 && { selectedProductIds: selectedProducts }) // Pass selected products to Stripe checkout
918
+ ))
919
+ .then(function (_a) {
920
+ var clientSecret = _a.clientSecret, publishableKey = _a.publishableKey, stripeAccount = _a.stripeAccount, businessName = _a.businessName, customerId = _a.customerId, isCheckout = _a.isCheckout, answerText = _a.answerText;
921
+ setAnswertext(answerText || '');
922
+ setIsCheckout(!!isCheckout);
923
+ setClientSecret(clientSecret);
924
+ setStripePromise(loadStripe(publishableKey, { stripeAccount: stripeAccount }));
925
+ setBusinessName(businessName);
926
+ setCustomerId(customerId);
927
+ })
928
+ .catch(function (e) {
929
+ console.error(e);
930
+ if (typeof (e === null || e === void 0 ? void 0 : e.message) === 'string') {
931
+ setError(e.message);
932
+ }
933
+ });
934
+ };
935
+ return (_jsxs(Grid, __assign({ container: true, direction: "column", spacing: 2 }, { children: [_jsx(Grid, __assign({ item: true }, { children: _jsxs(Typography, __assign({ variant: "h6" }, { children: ["Select Product", isSingleSelection_1 ? '' : 's'] })) })), availableProducts.map(function (product) {
936
+ var _a;
937
+ // Use real-time Stripe pricing if available, fallback to Tellescope pricing
938
+ var price = product.currentPrice || product.cost;
939
+ var priceAmount = (price === null || price === void 0 ? void 0 : price.amount) || 0;
940
+ var priceCurrency = (price === null || price === void 0 ? void 0 : price.currency) || 'USD';
941
+ return (_jsx(Grid, __assign({ item: true }, { children: _jsx(FormControlLabel, { control: isSingleSelection_1 ? (_jsx(Radio, { checked: selectedProducts.includes(product._id), onChange: function () { return handleProductSelection_1(product._id); } })) : (_jsx(Checkbox, { checked: selectedProducts.includes(product._id), onChange: function () { return handleProductSelection_1(product._id); } })), label: _jsxs(Box, { children: [_jsx(Typography, __assign({ variant: "body1", fontWeight: "bold" }, { children: product.title })), product.description && (_jsx(Typography, __assign({ variant: "body2", color: "textSecondary" }, { children: product.description }))), _jsxs(Typography, __assign({ variant: "body2", color: "primary" }, { children: ["$", (priceAmount / 100).toFixed(2), " ", priceCurrency.toUpperCase(), ((_a = product.currentPrice) === null || _a === void 0 ? void 0 : _a.isSubscription) && (_jsx(Typography, __assign({ component: "span", variant: "caption", sx: { ml: 0.5 } }, { children: "/month" })))] }))] }) }) }), product._id));
942
+ }), _jsx(Grid, __assign({ item: true }, { children: _jsx(Button, __assign({ variant: "contained", onClick: handleContinueToPayment, disabled: selectedProducts.length === 0, sx: { mt: 2 } }, { children: "Continue to Payment" })) }))] })));
943
+ }
813
944
  if (error) {
814
945
  return (_jsx(Typography, __assign({ color: "error" }, { children: error })));
815
946
  }
@@ -1009,14 +1140,14 @@ var get_other_answers = function (_value, typing) {
1009
1140
  return [];
1010
1141
  };
1011
1142
  export var DatabaseSelectInput = function (_a) {
1012
- var _b, _d, _e, _f, _g, _h;
1013
- var AddToDatabase = _a.AddToDatabase, field = _a.field, _value = _a.value, onChange = _a.onChange, onDatabaseSelect = _a.onDatabaseSelect, responses = _a.responses, size = _a.size, disabled = _a.disabled;
1014
- var _j = useState(''), typing = _j[0], setTyping = _j[1];
1015
- var _k = useDatabaseChoices({
1143
+ var _b, _d, _e, _f, _g, _h, _j, _k;
1144
+ var AddToDatabase = _a.AddToDatabase, field = _a.field, _value = _a.value, onChange = _a.onChange, onDatabaseSelect = _a.onDatabaseSelect, responses = _a.responses, size = _a.size, disabled = _a.disabled, enduser = _a.enduser;
1145
+ var _l = useState(''), typing = _l[0], setTyping = _l[1];
1146
+ var _m = useDatabaseChoices({
1016
1147
  databaseId: (_b = field.options) === null || _b === void 0 ? void 0 : _b.databaseId,
1017
1148
  field: field,
1018
1149
  otherAnswers: get_other_answers(_value, ((_d = field === null || field === void 0 ? void 0 : field.options) === null || _d === void 0 ? void 0 : _d.other) ? typing : undefined),
1019
- }), addChoice = _k.addChoice, choices = _k.choices, doneLoading = _k.doneLoading;
1150
+ }), addChoice = _m.addChoice, choices = _m.choices, doneLoading = _m.doneLoading;
1020
1151
  var value = React.useMemo(function () {
1021
1152
  var _a, _b;
1022
1153
  try {
@@ -1039,6 +1170,24 @@ export var DatabaseSelectInput = function (_a) {
1039
1170
  ? (_e = (_d = responses.find(function (r) { var _a, _b; return r.fieldId === ((_b = (_a = field.options) === null || _a === void 0 ? void 0 : _a.databaseFilter) === null || _b === void 0 ? void 0 : _b.fieldId); })) === null || _d === void 0 ? void 0 : _d.answer) === null || _e === void 0 ? void 0 : _e.value
1040
1171
  : undefined);
1041
1172
  }, [responses, (_e = field.options) === null || _e === void 0 ? void 0 : _e.databaseFilter]);
1173
+ // State filtering logic similar to Insurance component
1174
+ var addressQuestion = useMemo(function () { return responses === null || responses === void 0 ? void 0 : responses.find(function (r) {
1175
+ var _a;
1176
+ if (r.answer.type !== 'Address')
1177
+ return false;
1178
+ if (r.field.intakeField !== 'Address')
1179
+ return false;
1180
+ // make sure state is actually defined (in case of multiple address questions, where 1+ are blank)
1181
+ if (!((_a = r.answer.value) === null || _a === void 0 ? void 0 : _a.state))
1182
+ return false;
1183
+ return true;
1184
+ }); }, [responses]);
1185
+ var state = useMemo(function () {
1186
+ var _a, _b, _d, _e;
1187
+ return (((_a = field.options) === null || _a === void 0 ? void 0 : _a.filterByEnduserState)
1188
+ ? ((((_b = addressQuestion === null || addressQuestion === void 0 ? void 0 : addressQuestion.answer) === null || _b === void 0 ? void 0 : _b.type) === 'Address' ? (_e = (_d = addressQuestion === null || addressQuestion === void 0 ? void 0 : addressQuestion.answer) === null || _d === void 0 ? void 0 : _d.value) === null || _e === void 0 ? void 0 : _e.state : undefined) || (enduser === null || enduser === void 0 ? void 0 : enduser.state))
1189
+ : undefined);
1190
+ }, [enduser === null || enduser === void 0 ? void 0 : enduser.state, addressQuestion, (_f = field.options) === null || _f === void 0 ? void 0 : _f.filterByEnduserState]);
1042
1191
  var filteredChoicesWithPotentialDuplicates = useMemo(function () {
1043
1192
  var _a, _b;
1044
1193
  if (!choices)
@@ -1076,12 +1225,24 @@ export var DatabaseSelectInput = function (_a) {
1076
1225
  }
1077
1226
  return false;
1078
1227
  }));
1079
- }, [choices, filterResponse, (_f = field.options) === null || _f === void 0 ? void 0 : _f.databaseFilter, value]);
1228
+ }, [choices, filterResponse, (_g = field.options) === null || _g === void 0 ? void 0 : _g.databaseFilter, value]);
1229
+ // Apply state filtering as a secondary filter (doesn't modify existing logic)
1230
+ var stateFilteredChoices = useMemo(function () {
1231
+ var _a;
1232
+ if (!((_a = field.options) === null || _a === void 0 ? void 0 : _a.filterByEnduserState) || !state) {
1233
+ return filteredChoicesWithPotentialDuplicates;
1234
+ }
1235
+ return filteredChoicesWithPotentialDuplicates.filter(function (c) {
1236
+ var _a, _b;
1237
+ var recordState = ((_b = (_a = c.values.find(function (v) { var _a, _b; return ((_b = (_a = v.label) === null || _a === void 0 ? void 0 : _a.trim()) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'state'; })) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.toString()) || '';
1238
+ return !recordState || recordState === state;
1239
+ });
1240
+ }, [filteredChoicesWithPotentialDuplicates, (_h = field.options) === null || _h === void 0 ? void 0 : _h.filterByEnduserState, state]);
1080
1241
  var filteredChoices = useMemo(function () {
1081
1242
  var filtered = [];
1082
1243
  var uniques = new Set([]);
1083
- for (var _a = 0, filteredChoicesWithPotentialDuplicates_1 = filteredChoicesWithPotentialDuplicates; _a < filteredChoicesWithPotentialDuplicates_1.length; _a++) {
1084
- var c = filteredChoicesWithPotentialDuplicates_1[_a];
1244
+ for (var _a = 0, stateFilteredChoices_1 = stateFilteredChoices; _a < stateFilteredChoices_1.length; _a++) {
1245
+ var c = stateFilteredChoices_1[_a];
1085
1246
  var text = label_for_database_record(field, c);
1086
1247
  if (uniques.has(text))
1087
1248
  continue; // duplicate found
@@ -1089,7 +1250,7 @@ export var DatabaseSelectInput = function (_a) {
1089
1250
  filtered.push(c);
1090
1251
  }
1091
1252
  return filtered;
1092
- }, [field, filteredChoicesWithPotentialDuplicates]);
1253
+ }, [field, stateFilteredChoices]);
1093
1254
  if (!doneLoading)
1094
1255
  return _jsx(LinearProgress, {});
1095
1256
  return (_jsxs(_Fragment, { children: [_jsx(Autocomplete, { id: field.id, freeSolo: false, size: size, componentsProps: { popper: { sx: { wordBreak: "break-word" } } }, options: filteredChoices, multiple: true, getOptionLabel: function (o) { return (Array.isArray(o) // edge case
@@ -1119,7 +1280,7 @@ export var DatabaseSelectInput = function (_a) {
1119
1280
  // use custom Chip to ensure very long entries break properly (whitespace: normal)
1120
1281
  renderTags: function (value, getTagProps) {
1121
1282
  return value.map(function (value, index) { return (_jsx(Chip, __assign({ label: _jsx(Typography, __assign({ style: { whiteSpace: 'normal' } }, { children: Array.isArray(value) ? '' : label_for_database_record(field, value) })) }, getTagProps({ index: index }), { sx: { height: "100%", py: 0.5 } }))); });
1122
- } }), AddToDatabase && ((_g = field === null || field === void 0 ? void 0 : field.options) === null || _g === void 0 ? void 0 : _g.allowAddToDatabase) && (_jsx(AddToDatabase, { databaseId: (_h = field.options) === null || _h === void 0 ? void 0 : _h.databaseId, onAdd: addChoice }))] }));
1283
+ } }), AddToDatabase && ((_j = field === null || field === void 0 ? void 0 : field.options) === null || _j === void 0 ? void 0 : _j.allowAddToDatabase) && (_jsx(AddToDatabase, { databaseId: (_k = field.options) === null || _k === void 0 ? void 0 : _k.databaseId, onAdd: addChoice }))] }));
1123
1284
  };
1124
1285
  var displayTermsCache = undefined;
1125
1286
  var DRUGS_FOR_DISPLAY_TERM = {};