@exyconn/common 2.0.0 → 2.1.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.js CHANGED
@@ -8,17 +8,39 @@ var jwt = require('jsonwebtoken');
8
8
  var fs = require('fs');
9
9
  var axios = require('axios');
10
10
  var react = require('react');
11
+ var jsxRuntime = require('react/jsx-runtime');
12
+ var Yup = require('yup');
13
+ var formik = require('formik');
11
14
  var dateFns = require('date-fns');
12
15
  var dateFnsTz = require('date-fns-tz');
13
16
 
14
17
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
18
 
19
+ function _interopNamespace(e) {
20
+ if (e && e.__esModule) return e;
21
+ var n = Object.create(null);
22
+ if (e) {
23
+ Object.keys(e).forEach(function (k) {
24
+ if (k !== 'default') {
25
+ var d = Object.getOwnPropertyDescriptor(e, k);
26
+ Object.defineProperty(n, k, d.get ? d : {
27
+ enumerable: true,
28
+ get: function () { return e[k]; }
29
+ });
30
+ }
31
+ });
32
+ }
33
+ n.default = e;
34
+ return Object.freeze(n);
35
+ }
36
+
16
37
  var winston__default = /*#__PURE__*/_interopDefault(winston);
17
38
  var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
18
39
  var path__default = /*#__PURE__*/_interopDefault(path);
19
40
  var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
20
41
  var jwt__default = /*#__PURE__*/_interopDefault(jwt);
21
42
  var axios__default = /*#__PURE__*/_interopDefault(axios);
43
+ var Yup__namespace = /*#__PURE__*/_interopNamespace(Yup);
22
44
 
23
45
  var __defProp = Object.defineProperty;
24
46
  var __export = (target, all) => {
@@ -783,14 +805,24 @@ var client_exports = {};
783
805
  __export(client_exports, {
784
806
  ApiUrlBuilder: () => ApiUrlBuilder,
785
807
  ClientLogger: () => ClientLogger,
808
+ ContactForm: () => ContactForm,
786
809
  EventEmitter: () => EventEmitter,
810
+ LoginForm: () => LoginForm,
811
+ NewsletterForm: () => NewsletterForm,
812
+ RegisterForm: () => RegisterForm,
813
+ ThemeContext: () => ThemeContext,
814
+ ThemeProvider: () => ThemeProvider,
815
+ ThemeToggle: () => ThemeToggle,
816
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
787
817
  addDays: () => addDays,
818
+ adjustColor: () => adjustColor,
788
819
  appEvents: () => appEvents,
789
820
  camelToKebab: () => camelToKebab,
790
821
  capitalize: () => capitalize,
791
822
  capitalizeWords: () => capitalizeWords,
792
823
  checkPackage: () => checkPackage,
793
824
  clientLogger: () => clientLogger,
825
+ contactFormSchema: () => contactFormSchema,
794
826
  copyToClipboard: () => copyToClipboard,
795
827
  createApiEndpoints: () => createApiEndpoints,
796
828
  createApiUrlBuilder: () => createApiUrlBuilder,
@@ -799,21 +831,42 @@ __export(client_exports, {
799
831
  createErrorResponse: () => createErrorResponse,
800
832
  createEventEmitter: () => createEventEmitter,
801
833
  createHttpClient: () => createHttpClient,
834
+ createRegisterFormSchema: () => createRegisterFormSchema,
802
835
  createSuccessResponse: () => createSuccessResponse,
836
+ createTheme: () => createTheme,
837
+ createThemeFromBrand: () => createThemeFromBrand,
838
+ cssVar: () => cssVar,
839
+ deepMerge: () => deepMerge,
840
+ defaultDarkTheme: () => defaultDarkTheme,
841
+ defaultLightTheme: () => defaultLightTheme,
842
+ dummyBannerData: () => dummyBannerData,
843
+ dummyFaqItems: () => dummyFaqItems,
844
+ dummyFeatures: () => dummyFeatures,
845
+ dummyFooterData: () => dummyFooterData,
846
+ dummyHeaderData: () => dummyHeaderData,
847
+ dummyImage: () => dummyImage,
848
+ dummyPricingPlans: () => dummyPricingPlans,
849
+ dummyTestimonials: () => dummyTestimonials,
803
850
  endOfDay: () => endOfDay,
851
+ flattenToCssVars: () => flattenToCssVars,
804
852
  formatDate: () => formatDate,
805
853
  formatDateForInput: () => formatDateForInput,
806
854
  formatDateTime: () => formatDateTime,
807
855
  formatDateTimeForInput: () => formatDateTimeForInput,
808
856
  formatPackageCheckResult: () => formatPackageCheckResult2,
809
857
  formatRelativeTime: () => formatRelativeTime,
858
+ generateCssVars: () => generateCssVars,
810
859
  generateNcuCommand: () => generateNcuCommand2,
860
+ getContrastColor: () => getContrastColor,
811
861
  getErrorMessage: () => getErrorMessage,
812
862
  getNextPage: () => getNextPage,
813
863
  getPrevPage: () => getPrevPage,
814
864
  getResponseData: () => getResponseData,
865
+ getSystemColorScheme: () => getSystemColorScheme,
815
866
  hasData: () => hasData,
816
867
  hasMorePages: () => hasMorePages,
868
+ hexToRgba: () => hexToRgba,
869
+ injectCssVars: () => injectCssVars,
817
870
  isClipboardAvailable: () => isClipboardAvailable,
818
871
  isErrorResponse: () => isErrorResponse,
819
872
  isForbidden: () => isForbidden,
@@ -827,11 +880,20 @@ __export(client_exports, {
827
880
  isToday: () => isToday,
828
881
  isUnauthorized: () => isUnauthorized,
829
882
  kebabToCamel: () => kebabToCamel,
883
+ loadThemeFromUrl: () => loadThemeFromUrl,
884
+ loadThemeMode: () => loadThemeMode,
885
+ loginFormSchema: () => loginFormSchema,
886
+ loremIpsum: () => loremIpsum,
887
+ newsletterFormSchema: () => newsletterFormSchema,
830
888
  packageCheck: () => packageCheck,
831
889
  parseError: () => parseError,
832
890
  parseFullResponse: () => parseFullResponse,
833
891
  parseResponse: () => parseResponse,
834
892
  readFromClipboard: () => readFromClipboard,
893
+ registerFormSchema: () => registerFormSchema,
894
+ removeCssVars: () => removeCssVars,
895
+ resolveThemeMode: () => resolveThemeMode,
896
+ saveThemeMode: () => saveThemeMode,
835
897
  slugify: () => slugify,
836
898
  slugifyUnique: () => slugifyUnique,
837
899
  startOfDay: () => startOfDay,
@@ -889,7 +951,9 @@ __export(client_exports, {
889
951
  useSessionStorage: () => useSessionStorage_default,
890
952
  useSet: () => useSet_default,
891
953
  useSnackbar: () => useSnackbar_default,
954
+ useTheme: () => useTheme,
892
955
  useThemeDetector: () => useThemeDetector_default,
956
+ useThemeValue: () => useThemeValue,
893
957
  useThrottle: () => useThrottle_default,
894
958
  useTimeout: () => useTimeout_default,
895
959
  useToggle: () => useToggle_default,
@@ -1728,11 +1792,11 @@ function useDefault(initialValue, defaultValue) {
1728
1792
  }
1729
1793
  var useDefault_default = useDefault;
1730
1794
  function usePrevious(value, initialValue) {
1731
- const ref = react.useRef(initialValue);
1795
+ const ref2 = react.useRef(initialValue);
1732
1796
  react.useEffect(() => {
1733
- ref.current = value;
1797
+ ref2.current = value;
1734
1798
  }, [value]);
1735
- return ref.current;
1799
+ return ref2.current;
1736
1800
  }
1737
1801
  var usePrevious_default = usePrevious;
1738
1802
  function useObjectState(initialState) {
@@ -2658,7 +2722,7 @@ function useKeyPress(targetKey, callback, options = {}) {
2658
2722
  var useKeyPress_default = useKeyPress;
2659
2723
  function useHover(onHoverChange) {
2660
2724
  const [isHovered, setIsHovered] = react.useState(false);
2661
- const ref = react.useRef(null);
2725
+ const ref2 = react.useRef(null);
2662
2726
  const onMouseEnter = react.useCallback(() => {
2663
2727
  setIsHovered(true);
2664
2728
  onHoverChange?.(true);
@@ -2668,7 +2732,7 @@ function useHover(onHoverChange) {
2668
2732
  onHoverChange?.(false);
2669
2733
  }, [onHoverChange]);
2670
2734
  return {
2671
- ref,
2735
+ ref: ref2,
2672
2736
  isHovered,
2673
2737
  bind: {
2674
2738
  onMouseEnter,
@@ -2678,13 +2742,13 @@ function useHover(onHoverChange) {
2678
2742
  }
2679
2743
  var useHover_default = useHover;
2680
2744
  function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2681
- const ref = react.useRef(null);
2745
+ const ref2 = react.useRef(null);
2682
2746
  const savedCallback = react.useRef(callback);
2683
2747
  react.useEffect(() => {
2684
2748
  savedCallback.current = callback;
2685
2749
  }, [callback]);
2686
2750
  const handleClickAway = react.useCallback((event) => {
2687
- const el = ref.current;
2751
+ const el = ref2.current;
2688
2752
  if (!el || el.contains(event.target)) {
2689
2753
  return;
2690
2754
  }
@@ -2701,14 +2765,14 @@ function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2701
2765
  });
2702
2766
  };
2703
2767
  }, [events, handleClickAway]);
2704
- return ref;
2768
+ return ref2;
2705
2769
  }
2706
2770
  var useClickAway_default = useClickAway;
2707
- function useOnClickOutside(ref, handler, enabled = true) {
2771
+ function useOnClickOutside(ref2, handler, enabled = true) {
2708
2772
  react.useEffect(() => {
2709
2773
  if (!enabled) return;
2710
2774
  const listener = (event) => {
2711
- const el = ref?.current;
2775
+ const el = ref2?.current;
2712
2776
  if (!el || el.contains(event.target)) {
2713
2777
  return;
2714
2778
  }
@@ -2720,7 +2784,7 @@ function useOnClickOutside(ref, handler, enabled = true) {
2720
2784
  document.removeEventListener("mousedown", listener);
2721
2785
  document.removeEventListener("touchstart", listener);
2722
2786
  };
2723
- }, [ref, handler, enabled]);
2787
+ }, [ref2, handler, enabled]);
2724
2788
  }
2725
2789
  var useOnClickOutside_default = useOnClickOutside;
2726
2790
  function useLongPress(options = {}) {
@@ -2793,7 +2857,7 @@ function useLongPress(options = {}) {
2793
2857
  var useLongPress_default = useLongPress;
2794
2858
  function useMouse(options = {}) {
2795
2859
  const { enabled = true } = options;
2796
- const ref = react.useRef(null);
2860
+ const ref2 = react.useRef(null);
2797
2861
  const [position, setPosition] = react.useState({
2798
2862
  x: 0,
2799
2863
  y: 0,
@@ -2807,8 +2871,8 @@ function useMouse(options = {}) {
2807
2871
  let elementX = 0;
2808
2872
  let elementY = 0;
2809
2873
  let isInElement = false;
2810
- if (ref.current) {
2811
- const rect = ref.current.getBoundingClientRect();
2874
+ if (ref2.current) {
2875
+ const rect = ref2.current.getBoundingClientRect();
2812
2876
  elementX = event.clientX - rect.left;
2813
2877
  elementY = event.clientY - rect.top;
2814
2878
  isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
@@ -2831,7 +2895,7 @@ function useMouse(options = {}) {
2831
2895
  };
2832
2896
  }, [enabled, handleMouseMove]);
2833
2897
  return {
2834
- ref,
2898
+ ref: ref2,
2835
2899
  ...position
2836
2900
  };
2837
2901
  }
@@ -3743,7 +3807,7 @@ function useMeasure() {
3743
3807
  y: rect.y
3744
3808
  });
3745
3809
  }, []);
3746
- const ref = react.useCallback((node) => {
3810
+ const ref2 = react.useCallback((node) => {
3747
3811
  if (observerRef.current) {
3748
3812
  observerRef.current.disconnect();
3749
3813
  observerRef.current = null;
@@ -3790,7 +3854,7 @@ function useMeasure() {
3790
3854
  }
3791
3855
  };
3792
3856
  }, []);
3793
- return { ref, dimensions, measure };
3857
+ return { ref: ref2, dimensions, measure };
3794
3858
  }
3795
3859
  var useMeasure_default = useMeasure;
3796
3860
  function useIntersectionObserver(options = {}) {
@@ -3807,7 +3871,7 @@ function useIntersectionObserver(options = {}) {
3807
3871
  const elementRef = react.useRef(null);
3808
3872
  const observerRef = react.useRef(null);
3809
3873
  const frozen = react.useRef(false);
3810
- const ref = react.useCallback(
3874
+ const ref2 = react.useCallback(
3811
3875
  (node) => {
3812
3876
  if (observerRef.current) {
3813
3877
  observerRef.current.disconnect();
@@ -3843,7 +3907,7 @@ function useIntersectionObserver(options = {}) {
3843
3907
  }
3844
3908
  };
3845
3909
  }, []);
3846
- return { ref, isIntersecting, entry };
3910
+ return { ref: ref2, isIntersecting, entry };
3847
3911
  }
3848
3912
  var useIntersectionObserver_default = useIntersectionObserver;
3849
3913
  var DEFAULT_DURATION = 4e3;
@@ -3888,6 +3952,2616 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
3888
3952
  }
3889
3953
  var useSnackbar_default = useSnackbar;
3890
3954
 
3955
+ // src/client/web/theme/default-light-theme.ts
3956
+ var defaultLightTheme = {
3957
+ name: "default-light",
3958
+ mode: "light",
3959
+ colors: {
3960
+ brand: {
3961
+ primary: "#3b82f6",
3962
+ secondary: "#6366f1",
3963
+ accent: "#f59e0b",
3964
+ background: "#ffffff",
3965
+ foreground: "#111827"
3966
+ },
3967
+ semantic: {
3968
+ primary: "#3b82f6",
3969
+ primaryHover: "#2563eb",
3970
+ primaryActive: "#1d4ed8",
3971
+ primaryDisabled: "#93c5fd",
3972
+ secondary: "#6366f1",
3973
+ secondaryHover: "#4f46e5",
3974
+ secondaryActive: "#4338ca",
3975
+ secondaryDisabled: "#a5b4fc",
3976
+ accent: "#f59e0b",
3977
+ accentHover: "#d97706",
3978
+ success: "#22c55e",
3979
+ successHover: "#16a34a",
3980
+ warning: "#f59e0b",
3981
+ warningHover: "#d97706",
3982
+ error: "#ef4444",
3983
+ errorHover: "#dc2626",
3984
+ info: "#3b82f6",
3985
+ infoHover: "#2563eb"
3986
+ },
3987
+ background: {
3988
+ default: "#ffffff",
3989
+ paper: "#f9fafb",
3990
+ card: "#ffffff",
3991
+ overlay: "rgba(0, 0, 0, 0.5)",
3992
+ input: "#ffffff",
3993
+ disabled: "#f3f4f6",
3994
+ hover: "#f3f4f6",
3995
+ selected: "#eff6ff"
3996
+ },
3997
+ surface: {
3998
+ light: "#f9fafb",
3999
+ main: "#f3f4f6",
4000
+ dark: "#e5e7eb"
4001
+ },
4002
+ text: {
4003
+ primary: "#111827",
4004
+ secondary: "#6b7280",
4005
+ disabled: "#9ca3af",
4006
+ placeholder: "#9ca3af",
4007
+ link: "#3b82f6",
4008
+ linkHover: "#2563eb",
4009
+ inverse: "#ffffff",
4010
+ onPrimary: "#ffffff",
4011
+ onSecondary: "#ffffff"
4012
+ },
4013
+ border: {
4014
+ default: "#e5e7eb",
4015
+ light: "#f3f4f6",
4016
+ dark: "#d1d5db",
4017
+ focus: "#3b82f6",
4018
+ error: "#ef4444",
4019
+ success: "#22c55e",
4020
+ disabled: "#e5e7eb"
4021
+ }
4022
+ },
4023
+ shadows: {
4024
+ none: "none",
4025
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4026
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4027
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4028
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4029
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
4030
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4031
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
4032
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4033
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4034
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4035
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4036
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4037
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
4038
+ },
4039
+ typography: {
4040
+ fontFamily: {
4041
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
4042
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
4043
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
4044
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
4045
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
4046
+ },
4047
+ fontSize: {
4048
+ xs: "0.75rem",
4049
+ sm: "0.875rem",
4050
+ base: "1rem",
4051
+ lg: "1.125rem",
4052
+ xl: "1.25rem",
4053
+ "2xl": "1.5rem",
4054
+ "3xl": "1.875rem",
4055
+ "4xl": "2.25rem",
4056
+ "5xl": "3rem",
4057
+ "6xl": "3.75rem"
4058
+ },
4059
+ fontWeight: {
4060
+ light: 300,
4061
+ normal: 400,
4062
+ medium: 500,
4063
+ semibold: 600,
4064
+ bold: 700,
4065
+ extrabold: 800
4066
+ },
4067
+ lineHeight: {
4068
+ none: 1,
4069
+ tight: 1.25,
4070
+ snug: 1.375,
4071
+ normal: 1.5,
4072
+ relaxed: 1.625,
4073
+ loose: 2
4074
+ }
4075
+ },
4076
+ spacing: {
4077
+ 0: "0",
4078
+ px: "1px",
4079
+ 0.5: "0.125rem",
4080
+ 1: "0.25rem",
4081
+ 1.5: "0.375rem",
4082
+ 2: "0.5rem",
4083
+ 2.5: "0.625rem",
4084
+ 3: "0.75rem",
4085
+ 3.5: "0.875rem",
4086
+ 4: "1rem",
4087
+ 5: "1.25rem",
4088
+ 6: "1.5rem",
4089
+ 7: "1.75rem",
4090
+ 8: "2rem",
4091
+ 9: "2.25rem",
4092
+ 10: "2.5rem",
4093
+ 11: "2.75rem",
4094
+ 12: "3rem",
4095
+ 14: "3.5rem",
4096
+ 16: "4rem",
4097
+ 20: "5rem",
4098
+ 24: "6rem",
4099
+ 28: "7rem",
4100
+ 32: "8rem",
4101
+ 36: "9rem",
4102
+ 40: "10rem",
4103
+ 44: "11rem",
4104
+ 48: "12rem",
4105
+ 52: "13rem",
4106
+ 56: "14rem",
4107
+ 60: "15rem",
4108
+ 64: "16rem",
4109
+ 72: "18rem",
4110
+ 80: "20rem",
4111
+ 96: "24rem"
4112
+ },
4113
+ borderRadius: {
4114
+ none: "0",
4115
+ sm: "0.125rem",
4116
+ default: "0.25rem",
4117
+ md: "0.375rem",
4118
+ lg: "0.5rem",
4119
+ xl: "0.75rem",
4120
+ "2xl": "1rem",
4121
+ "3xl": "1.5rem",
4122
+ full: "9999px"
4123
+ },
4124
+ breakpoints: {
4125
+ xs: "475px",
4126
+ sm: "640px",
4127
+ md: "768px",
4128
+ lg: "1024px",
4129
+ xl: "1280px",
4130
+ "2xl": "1536px"
4131
+ },
4132
+ zIndex: {
4133
+ hide: -1,
4134
+ auto: "auto",
4135
+ base: 0,
4136
+ dropdown: 1e3,
4137
+ sticky: 1020,
4138
+ fixed: 1030,
4139
+ modalBackdrop: 1040,
4140
+ modal: 1050,
4141
+ popover: 1060,
4142
+ tooltip: 1070,
4143
+ toast: 1080
4144
+ },
4145
+ transitions: {
4146
+ none: "none",
4147
+ fast: "150ms ease-in-out",
4148
+ normal: "200ms ease-in-out",
4149
+ slow: "300ms ease-in-out",
4150
+ slower: "500ms ease-in-out",
4151
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
4152
+ transform: "transform 200ms ease-in-out",
4153
+ opacity: "opacity 200ms ease-in-out",
4154
+ shadow: "box-shadow 200ms ease-in-out",
4155
+ all: "all 200ms ease-in-out"
4156
+ },
4157
+ components: {
4158
+ button: {
4159
+ bg: "#3b82f6",
4160
+ bgHover: "#2563eb",
4161
+ bgActive: "#1d4ed8",
4162
+ bgDisabled: "#93c5fd",
4163
+ color: "#ffffff",
4164
+ colorHover: "#ffffff",
4165
+ colorDisabled: "#ffffff",
4166
+ border: "transparent",
4167
+ borderHover: "transparent",
4168
+ borderWidth: "1px",
4169
+ borderRadius: "0.375rem",
4170
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4171
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.1)",
4172
+ paddingX: "1rem",
4173
+ paddingY: "0.5rem",
4174
+ fontSize: "0.875rem",
4175
+ fontWeight: 500,
4176
+ variants: {
4177
+ primary: {
4178
+ bg: "#3b82f6",
4179
+ bgHover: "#2563eb",
4180
+ color: "#ffffff"
4181
+ },
4182
+ secondary: {
4183
+ bg: "#6366f1",
4184
+ bgHover: "#4f46e5",
4185
+ color: "#ffffff"
4186
+ },
4187
+ outline: {
4188
+ bg: "transparent",
4189
+ bgHover: "#f3f4f6",
4190
+ color: "#374151",
4191
+ border: "#d1d5db",
4192
+ borderHover: "#9ca3af"
4193
+ },
4194
+ ghost: {
4195
+ bg: "transparent",
4196
+ bgHover: "#f3f4f6",
4197
+ color: "#374151",
4198
+ shadow: "none",
4199
+ shadowHover: "none"
4200
+ },
4201
+ link: {
4202
+ bg: "transparent",
4203
+ bgHover: "transparent",
4204
+ color: "#3b82f6",
4205
+ colorHover: "#2563eb",
4206
+ shadow: "none",
4207
+ shadowHover: "none",
4208
+ paddingX: "0",
4209
+ paddingY: "0"
4210
+ },
4211
+ danger: {
4212
+ bg: "#ef4444",
4213
+ bgHover: "#dc2626",
4214
+ color: "#ffffff"
4215
+ },
4216
+ success: {
4217
+ bg: "#22c55e",
4218
+ bgHover: "#16a34a",
4219
+ color: "#ffffff"
4220
+ }
4221
+ },
4222
+ sizes: {
4223
+ xs: {
4224
+ paddingX: "0.5rem",
4225
+ paddingY: "0.25rem",
4226
+ fontSize: "0.75rem"
4227
+ },
4228
+ sm: {
4229
+ paddingX: "0.75rem",
4230
+ paddingY: "0.375rem",
4231
+ fontSize: "0.875rem"
4232
+ },
4233
+ md: {
4234
+ paddingX: "1rem",
4235
+ paddingY: "0.5rem",
4236
+ fontSize: "0.875rem"
4237
+ },
4238
+ lg: {
4239
+ paddingX: "1.25rem",
4240
+ paddingY: "0.625rem",
4241
+ fontSize: "1rem"
4242
+ },
4243
+ xl: {
4244
+ paddingX: "1.5rem",
4245
+ paddingY: "0.75rem",
4246
+ fontSize: "1.125rem"
4247
+ }
4248
+ }
4249
+ },
4250
+ input: {
4251
+ bg: "#ffffff",
4252
+ bgFocus: "#ffffff",
4253
+ bgDisabled: "#f3f4f6",
4254
+ bgError: "#fef2f2",
4255
+ color: "#111827",
4256
+ colorPlaceholder: "#9ca3af",
4257
+ colorDisabled: "#9ca3af",
4258
+ border: "#d1d5db",
4259
+ borderFocus: "#3b82f6",
4260
+ borderError: "#ef4444",
4261
+ borderWidth: "1px",
4262
+ borderRadius: "0.375rem",
4263
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4264
+ shadowFocus: "0 0 0 3px rgb(59 130 246 / 0.1)",
4265
+ paddingX: "0.75rem",
4266
+ paddingY: "0.5rem",
4267
+ fontSize: "0.875rem",
4268
+ labelColor: "#374151",
4269
+ labelFontSize: "0.875rem",
4270
+ labelFontWeight: 500,
4271
+ helperColor: "#6b7280",
4272
+ errorColor: "#ef4444",
4273
+ sizes: {
4274
+ sm: {
4275
+ paddingX: "0.5rem",
4276
+ paddingY: "0.375rem",
4277
+ fontSize: "0.75rem"
4278
+ },
4279
+ md: {
4280
+ paddingX: "0.75rem",
4281
+ paddingY: "0.5rem",
4282
+ fontSize: "0.875rem"
4283
+ },
4284
+ lg: {
4285
+ paddingX: "1rem",
4286
+ paddingY: "0.625rem",
4287
+ fontSize: "1rem"
4288
+ }
4289
+ }
4290
+ },
4291
+ card: {
4292
+ bg: "#ffffff",
4293
+ bgHover: "#ffffff",
4294
+ border: "#e5e7eb",
4295
+ borderWidth: "1px",
4296
+ borderRadius: "0.5rem",
4297
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4298
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
4299
+ padding: "1.5rem",
4300
+ headerBg: "#f9fafb",
4301
+ headerBorder: "#e5e7eb",
4302
+ headerPadding: "1rem 1.5rem",
4303
+ footerBg: "#f9fafb",
4304
+ footerBorder: "#e5e7eb",
4305
+ footerPadding: "1rem 1.5rem"
4306
+ },
4307
+ header: {
4308
+ bg: "#ffffff",
4309
+ bgScrolled: "rgba(255, 255, 255, 0.95)",
4310
+ color: "#111827",
4311
+ border: "#e5e7eb",
4312
+ shadow: "none",
4313
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4314
+ height: "4rem",
4315
+ paddingX: "1.5rem",
4316
+ logoHeight: "2rem",
4317
+ navColor: "#374151",
4318
+ navColorHover: "#111827",
4319
+ navColorActive: "#3b82f6",
4320
+ navFontSize: "0.875rem",
4321
+ navFontWeight: 500,
4322
+ mobileMenuBg: "#ffffff",
4323
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)"
4324
+ },
4325
+ footer: {
4326
+ bg: "#111827",
4327
+ color: "#d1d5db",
4328
+ colorMuted: "#9ca3af",
4329
+ border: "#374151",
4330
+ padding: "4rem 1.5rem",
4331
+ linkColor: "#d1d5db",
4332
+ linkColorHover: "#ffffff",
4333
+ headingColor: "#ffffff",
4334
+ headingFontSize: "1rem",
4335
+ headingFontWeight: 600,
4336
+ copyrightBg: "#0f172a",
4337
+ copyrightColor: "#9ca3af"
4338
+ },
4339
+ banner: {
4340
+ bg: "#eff6ff",
4341
+ color: "#1e40af",
4342
+ border: "#bfdbfe",
4343
+ borderRadius: "0.5rem",
4344
+ padding: "1rem 1.5rem",
4345
+ shadow: "none",
4346
+ closeBg: "transparent",
4347
+ closeColor: "#1e40af",
4348
+ variants: {
4349
+ info: {
4350
+ bg: "#eff6ff",
4351
+ color: "#1e40af",
4352
+ border: "#bfdbfe"
4353
+ },
4354
+ success: {
4355
+ bg: "#f0fdf4",
4356
+ color: "#166534",
4357
+ border: "#bbf7d0"
4358
+ },
4359
+ warning: {
4360
+ bg: "#fffbeb",
4361
+ color: "#92400e",
4362
+ border: "#fde68a"
4363
+ },
4364
+ error: {
4365
+ bg: "#fef2f2",
4366
+ color: "#991b1b",
4367
+ border: "#fecaca"
4368
+ },
4369
+ promo: {
4370
+ bg: "#faf5ff",
4371
+ color: "#6b21a8",
4372
+ border: "#e9d5ff"
4373
+ }
4374
+ }
4375
+ },
4376
+ loader: {
4377
+ color: "#3b82f6",
4378
+ colorSecondary: "#e5e7eb",
4379
+ size: "2.5rem",
4380
+ borderWidth: "3px",
4381
+ overlayBg: "rgba(255, 255, 255, 0.8)",
4382
+ overlayOpacity: 1,
4383
+ sizes: {
4384
+ xs: "1rem",
4385
+ sm: "1.5rem",
4386
+ md: "2.5rem",
4387
+ lg: "3.5rem",
4388
+ xl: "5rem"
4389
+ }
4390
+ },
4391
+ modal: {
4392
+ bg: "#ffffff",
4393
+ color: "#111827",
4394
+ border: "#e5e7eb",
4395
+ borderRadius: "0.5rem",
4396
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4397
+ padding: "1.5rem",
4398
+ overlayBg: "rgba(0, 0, 0, 0.5)",
4399
+ overlayOpacity: 1,
4400
+ headerBg: "#ffffff",
4401
+ headerBorder: "#e5e7eb",
4402
+ headerPadding: "1rem 1.5rem",
4403
+ footerBg: "#f9fafb",
4404
+ footerBorder: "#e5e7eb",
4405
+ footerPadding: "1rem 1.5rem",
4406
+ closeBg: "transparent",
4407
+ closeColor: "#6b7280",
4408
+ closeHoverBg: "#f3f4f6",
4409
+ sizes: {
4410
+ sm: "24rem",
4411
+ md: "32rem",
4412
+ lg: "48rem",
4413
+ xl: "64rem",
4414
+ full: "100%"
4415
+ }
4416
+ },
4417
+ toast: {
4418
+ bg: "#ffffff",
4419
+ color: "#111827",
4420
+ border: "#e5e7eb",
4421
+ borderRadius: "0.5rem",
4422
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
4423
+ padding: "1rem",
4424
+ variants: {
4425
+ success: {
4426
+ bg: "#f0fdf4",
4427
+ color: "#166534",
4428
+ border: "#bbf7d0"
4429
+ },
4430
+ error: {
4431
+ bg: "#fef2f2",
4432
+ color: "#991b1b",
4433
+ border: "#fecaca"
4434
+ },
4435
+ warning: {
4436
+ bg: "#fffbeb",
4437
+ color: "#92400e",
4438
+ border: "#fde68a"
4439
+ },
4440
+ info: {
4441
+ bg: "#eff6ff",
4442
+ color: "#1e40af",
4443
+ border: "#bfdbfe"
4444
+ }
4445
+ }
4446
+ },
4447
+ newsletter: {
4448
+ bg: "#f9fafb",
4449
+ color: "#111827",
4450
+ border: "#e5e7eb",
4451
+ borderRadius: "0.5rem",
4452
+ padding: "2rem",
4453
+ titleColor: "#111827",
4454
+ titleFontSize: "1.5rem",
4455
+ descColor: "#6b7280",
4456
+ descFontSize: "1rem",
4457
+ inputBg: "#ffffff",
4458
+ inputBorder: "#d1d5db",
4459
+ buttonBg: "#3b82f6",
4460
+ buttonColor: "#ffffff"
4461
+ }
4462
+ }
4463
+ };
4464
+
4465
+ // src/client/web/theme/default-dark-theme.ts
4466
+ var defaultDarkTheme = {
4467
+ name: "default-dark",
4468
+ mode: "dark",
4469
+ colors: {
4470
+ brand: {
4471
+ primary: "#60a5fa",
4472
+ secondary: "#818cf8",
4473
+ accent: "#fbbf24",
4474
+ background: "#0f172a",
4475
+ foreground: "#f8fafc"
4476
+ },
4477
+ semantic: {
4478
+ primary: "#60a5fa",
4479
+ primaryHover: "#3b82f6",
4480
+ primaryActive: "#2563eb",
4481
+ primaryDisabled: "#1e3a5f",
4482
+ secondary: "#818cf8",
4483
+ secondaryHover: "#6366f1",
4484
+ secondaryActive: "#4f46e5",
4485
+ secondaryDisabled: "#312e81",
4486
+ accent: "#fbbf24",
4487
+ accentHover: "#f59e0b",
4488
+ success: "#4ade80",
4489
+ successHover: "#22c55e",
4490
+ warning: "#fbbf24",
4491
+ warningHover: "#f59e0b",
4492
+ error: "#f87171",
4493
+ errorHover: "#ef4444",
4494
+ info: "#60a5fa",
4495
+ infoHover: "#3b82f6"
4496
+ },
4497
+ background: {
4498
+ default: "#0f172a",
4499
+ paper: "#1e293b",
4500
+ card: "#1e293b",
4501
+ overlay: "rgba(0, 0, 0, 0.7)",
4502
+ input: "#1e293b",
4503
+ disabled: "#334155",
4504
+ hover: "#334155",
4505
+ selected: "#1e3a5f"
4506
+ },
4507
+ surface: {
4508
+ light: "#334155",
4509
+ main: "#1e293b",
4510
+ dark: "#0f172a"
4511
+ },
4512
+ text: {
4513
+ primary: "#f8fafc",
4514
+ secondary: "#94a3b8",
4515
+ disabled: "#64748b",
4516
+ placeholder: "#64748b",
4517
+ link: "#60a5fa",
4518
+ linkHover: "#3b82f6",
4519
+ inverse: "#0f172a",
4520
+ onPrimary: "#0f172a",
4521
+ onSecondary: "#0f172a"
4522
+ },
4523
+ border: {
4524
+ default: "#334155",
4525
+ light: "#475569",
4526
+ dark: "#1e293b",
4527
+ focus: "#60a5fa",
4528
+ error: "#f87171",
4529
+ success: "#4ade80",
4530
+ disabled: "#334155"
4531
+ }
4532
+ },
4533
+ shadows: {
4534
+ none: "none",
4535
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
4536
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4)",
4537
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",
4538
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",
4539
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)",
4540
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4541
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.3)",
4542
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4543
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
4544
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4545
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4546
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4547
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
4548
+ },
4549
+ typography: {
4550
+ fontFamily: {
4551
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
4552
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
4553
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
4554
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
4555
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
4556
+ },
4557
+ fontSize: {
4558
+ xs: "0.75rem",
4559
+ sm: "0.875rem",
4560
+ base: "1rem",
4561
+ lg: "1.125rem",
4562
+ xl: "1.25rem",
4563
+ "2xl": "1.5rem",
4564
+ "3xl": "1.875rem",
4565
+ "4xl": "2.25rem",
4566
+ "5xl": "3rem",
4567
+ "6xl": "3.75rem"
4568
+ },
4569
+ fontWeight: {
4570
+ light: 300,
4571
+ normal: 400,
4572
+ medium: 500,
4573
+ semibold: 600,
4574
+ bold: 700,
4575
+ extrabold: 800
4576
+ },
4577
+ lineHeight: {
4578
+ none: 1,
4579
+ tight: 1.25,
4580
+ snug: 1.375,
4581
+ normal: 1.5,
4582
+ relaxed: 1.625,
4583
+ loose: 2
4584
+ }
4585
+ },
4586
+ spacing: {
4587
+ 0: "0",
4588
+ px: "1px",
4589
+ 0.5: "0.125rem",
4590
+ 1: "0.25rem",
4591
+ 1.5: "0.375rem",
4592
+ 2: "0.5rem",
4593
+ 2.5: "0.625rem",
4594
+ 3: "0.75rem",
4595
+ 3.5: "0.875rem",
4596
+ 4: "1rem",
4597
+ 5: "1.25rem",
4598
+ 6: "1.5rem",
4599
+ 7: "1.75rem",
4600
+ 8: "2rem",
4601
+ 9: "2.25rem",
4602
+ 10: "2.5rem",
4603
+ 11: "2.75rem",
4604
+ 12: "3rem",
4605
+ 14: "3.5rem",
4606
+ 16: "4rem",
4607
+ 20: "5rem",
4608
+ 24: "6rem",
4609
+ 28: "7rem",
4610
+ 32: "8rem",
4611
+ 36: "9rem",
4612
+ 40: "10rem",
4613
+ 44: "11rem",
4614
+ 48: "12rem",
4615
+ 52: "13rem",
4616
+ 56: "14rem",
4617
+ 60: "15rem",
4618
+ 64: "16rem",
4619
+ 72: "18rem",
4620
+ 80: "20rem",
4621
+ 96: "24rem"
4622
+ },
4623
+ borderRadius: {
4624
+ none: "0",
4625
+ sm: "0.125rem",
4626
+ default: "0.25rem",
4627
+ md: "0.375rem",
4628
+ lg: "0.5rem",
4629
+ xl: "0.75rem",
4630
+ "2xl": "1rem",
4631
+ "3xl": "1.5rem",
4632
+ full: "9999px"
4633
+ },
4634
+ breakpoints: {
4635
+ xs: "475px",
4636
+ sm: "640px",
4637
+ md: "768px",
4638
+ lg: "1024px",
4639
+ xl: "1280px",
4640
+ "2xl": "1536px"
4641
+ },
4642
+ zIndex: {
4643
+ hide: -1,
4644
+ auto: "auto",
4645
+ base: 0,
4646
+ dropdown: 1e3,
4647
+ sticky: 1020,
4648
+ fixed: 1030,
4649
+ modalBackdrop: 1040,
4650
+ modal: 1050,
4651
+ popover: 1060,
4652
+ tooltip: 1070,
4653
+ toast: 1080
4654
+ },
4655
+ transitions: {
4656
+ none: "none",
4657
+ fast: "150ms ease-in-out",
4658
+ normal: "200ms ease-in-out",
4659
+ slow: "300ms ease-in-out",
4660
+ slower: "500ms ease-in-out",
4661
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
4662
+ transform: "transform 200ms ease-in-out",
4663
+ opacity: "opacity 200ms ease-in-out",
4664
+ shadow: "box-shadow 200ms ease-in-out",
4665
+ all: "all 200ms ease-in-out"
4666
+ },
4667
+ components: {
4668
+ button: {
4669
+ bg: "#60a5fa",
4670
+ bgHover: "#3b82f6",
4671
+ bgActive: "#2563eb",
4672
+ bgDisabled: "#1e3a5f",
4673
+ color: "#0f172a",
4674
+ colorHover: "#0f172a",
4675
+ colorDisabled: "#64748b",
4676
+ border: "transparent",
4677
+ borderHover: "transparent",
4678
+ borderWidth: "1px",
4679
+ borderRadius: "0.375rem",
4680
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4681
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
4682
+ paddingX: "1rem",
4683
+ paddingY: "0.5rem",
4684
+ fontSize: "0.875rem",
4685
+ fontWeight: 500,
4686
+ variants: {
4687
+ primary: {
4688
+ bg: "#60a5fa",
4689
+ bgHover: "#3b82f6",
4690
+ color: "#0f172a"
4691
+ },
4692
+ secondary: {
4693
+ bg: "#818cf8",
4694
+ bgHover: "#6366f1",
4695
+ color: "#0f172a"
4696
+ },
4697
+ outline: {
4698
+ bg: "transparent",
4699
+ bgHover: "#334155",
4700
+ color: "#f8fafc",
4701
+ border: "#475569",
4702
+ borderHover: "#64748b"
4703
+ },
4704
+ ghost: {
4705
+ bg: "transparent",
4706
+ bgHover: "#334155",
4707
+ color: "#f8fafc",
4708
+ shadow: "none",
4709
+ shadowHover: "none"
4710
+ },
4711
+ link: {
4712
+ bg: "transparent",
4713
+ bgHover: "transparent",
4714
+ color: "#60a5fa",
4715
+ colorHover: "#3b82f6",
4716
+ shadow: "none",
4717
+ shadowHover: "none",
4718
+ paddingX: "0",
4719
+ paddingY: "0"
4720
+ },
4721
+ danger: {
4722
+ bg: "#f87171",
4723
+ bgHover: "#ef4444",
4724
+ color: "#0f172a"
4725
+ },
4726
+ success: {
4727
+ bg: "#4ade80",
4728
+ bgHover: "#22c55e",
4729
+ color: "#0f172a"
4730
+ }
4731
+ },
4732
+ sizes: {
4733
+ xs: {
4734
+ paddingX: "0.5rem",
4735
+ paddingY: "0.25rem",
4736
+ fontSize: "0.75rem"
4737
+ },
4738
+ sm: {
4739
+ paddingX: "0.75rem",
4740
+ paddingY: "0.375rem",
4741
+ fontSize: "0.875rem"
4742
+ },
4743
+ md: {
4744
+ paddingX: "1rem",
4745
+ paddingY: "0.5rem",
4746
+ fontSize: "0.875rem"
4747
+ },
4748
+ lg: {
4749
+ paddingX: "1.25rem",
4750
+ paddingY: "0.625rem",
4751
+ fontSize: "1rem"
4752
+ },
4753
+ xl: {
4754
+ paddingX: "1.5rem",
4755
+ paddingY: "0.75rem",
4756
+ fontSize: "1.125rem"
4757
+ }
4758
+ }
4759
+ },
4760
+ input: {
4761
+ bg: "#1e293b",
4762
+ bgFocus: "#1e293b",
4763
+ bgDisabled: "#334155",
4764
+ bgError: "#450a0a",
4765
+ color: "#f8fafc",
4766
+ colorPlaceholder: "#64748b",
4767
+ colorDisabled: "#64748b",
4768
+ border: "#475569",
4769
+ borderFocus: "#60a5fa",
4770
+ borderError: "#f87171",
4771
+ borderWidth: "1px",
4772
+ borderRadius: "0.375rem",
4773
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
4774
+ shadowFocus: "0 0 0 3px rgb(96 165 250 / 0.2)",
4775
+ paddingX: "0.75rem",
4776
+ paddingY: "0.5rem",
4777
+ fontSize: "0.875rem",
4778
+ labelColor: "#e2e8f0",
4779
+ labelFontSize: "0.875rem",
4780
+ labelFontWeight: 500,
4781
+ helperColor: "#94a3b8",
4782
+ errorColor: "#f87171",
4783
+ sizes: {
4784
+ sm: {
4785
+ paddingX: "0.5rem",
4786
+ paddingY: "0.375rem",
4787
+ fontSize: "0.75rem"
4788
+ },
4789
+ md: {
4790
+ paddingX: "0.75rem",
4791
+ paddingY: "0.5rem",
4792
+ fontSize: "0.875rem"
4793
+ },
4794
+ lg: {
4795
+ paddingX: "1rem",
4796
+ paddingY: "0.625rem",
4797
+ fontSize: "1rem"
4798
+ }
4799
+ }
4800
+ },
4801
+ card: {
4802
+ bg: "#1e293b",
4803
+ bgHover: "#1e293b",
4804
+ border: "#334155",
4805
+ borderWidth: "1px",
4806
+ borderRadius: "0.5rem",
4807
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4808
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4809
+ padding: "1.5rem",
4810
+ headerBg: "#0f172a",
4811
+ headerBorder: "#334155",
4812
+ headerPadding: "1rem 1.5rem",
4813
+ footerBg: "#0f172a",
4814
+ footerBorder: "#334155",
4815
+ footerPadding: "1rem 1.5rem"
4816
+ },
4817
+ header: {
4818
+ bg: "#0f172a",
4819
+ bgScrolled: "rgba(15, 23, 42, 0.95)",
4820
+ color: "#f8fafc",
4821
+ border: "#334155",
4822
+ shadow: "none",
4823
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
4824
+ height: "4rem",
4825
+ paddingX: "1.5rem",
4826
+ logoHeight: "2rem",
4827
+ navColor: "#94a3b8",
4828
+ navColorHover: "#f8fafc",
4829
+ navColorActive: "#60a5fa",
4830
+ navFontSize: "0.875rem",
4831
+ navFontWeight: 500,
4832
+ mobileMenuBg: "#1e293b",
4833
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
4834
+ },
4835
+ footer: {
4836
+ bg: "#020617",
4837
+ color: "#94a3b8",
4838
+ colorMuted: "#64748b",
4839
+ border: "#1e293b",
4840
+ padding: "4rem 1.5rem",
4841
+ linkColor: "#94a3b8",
4842
+ linkColorHover: "#f8fafc",
4843
+ headingColor: "#f8fafc",
4844
+ headingFontSize: "1rem",
4845
+ headingFontWeight: 600,
4846
+ copyrightBg: "#0f172a",
4847
+ copyrightColor: "#64748b"
4848
+ },
4849
+ banner: {
4850
+ bg: "#1e3a5f",
4851
+ color: "#bfdbfe",
4852
+ border: "#3b82f6",
4853
+ borderRadius: "0.5rem",
4854
+ padding: "1rem 1.5rem",
4855
+ shadow: "none",
4856
+ closeBg: "transparent",
4857
+ closeColor: "#bfdbfe",
4858
+ variants: {
4859
+ info: {
4860
+ bg: "#1e3a5f",
4861
+ color: "#bfdbfe",
4862
+ border: "#3b82f6"
4863
+ },
4864
+ success: {
4865
+ bg: "#14532d",
4866
+ color: "#bbf7d0",
4867
+ border: "#22c55e"
4868
+ },
4869
+ warning: {
4870
+ bg: "#78350f",
4871
+ color: "#fde68a",
4872
+ border: "#f59e0b"
4873
+ },
4874
+ error: {
4875
+ bg: "#7f1d1d",
4876
+ color: "#fecaca",
4877
+ border: "#ef4444"
4878
+ },
4879
+ promo: {
4880
+ bg: "#581c87",
4881
+ color: "#e9d5ff",
4882
+ border: "#a855f7"
4883
+ }
4884
+ }
4885
+ },
4886
+ loader: {
4887
+ color: "#60a5fa",
4888
+ colorSecondary: "#334155",
4889
+ size: "2.5rem",
4890
+ borderWidth: "3px",
4891
+ overlayBg: "rgba(15, 23, 42, 0.8)",
4892
+ overlayOpacity: 1,
4893
+ sizes: {
4894
+ xs: "1rem",
4895
+ sm: "1.5rem",
4896
+ md: "2.5rem",
4897
+ lg: "3.5rem",
4898
+ xl: "5rem"
4899
+ }
4900
+ },
4901
+ modal: {
4902
+ bg: "#1e293b",
4903
+ color: "#f8fafc",
4904
+ border: "#334155",
4905
+ borderRadius: "0.5rem",
4906
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
4907
+ padding: "1.5rem",
4908
+ overlayBg: "rgba(0, 0, 0, 0.7)",
4909
+ overlayOpacity: 1,
4910
+ headerBg: "#1e293b",
4911
+ headerBorder: "#334155",
4912
+ headerPadding: "1rem 1.5rem",
4913
+ footerBg: "#0f172a",
4914
+ footerBorder: "#334155",
4915
+ footerPadding: "1rem 1.5rem",
4916
+ closeBg: "transparent",
4917
+ closeColor: "#94a3b8",
4918
+ closeHoverBg: "#334155",
4919
+ sizes: {
4920
+ sm: "24rem",
4921
+ md: "32rem",
4922
+ lg: "48rem",
4923
+ xl: "64rem",
4924
+ full: "100%"
4925
+ }
4926
+ },
4927
+ toast: {
4928
+ bg: "#1e293b",
4929
+ color: "#f8fafc",
4930
+ border: "#334155",
4931
+ borderRadius: "0.5rem",
4932
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
4933
+ padding: "1rem",
4934
+ variants: {
4935
+ success: {
4936
+ bg: "#14532d",
4937
+ color: "#bbf7d0",
4938
+ border: "#22c55e"
4939
+ },
4940
+ error: {
4941
+ bg: "#7f1d1d",
4942
+ color: "#fecaca",
4943
+ border: "#ef4444"
4944
+ },
4945
+ warning: {
4946
+ bg: "#78350f",
4947
+ color: "#fde68a",
4948
+ border: "#f59e0b"
4949
+ },
4950
+ info: {
4951
+ bg: "#1e3a5f",
4952
+ color: "#bfdbfe",
4953
+ border: "#3b82f6"
4954
+ }
4955
+ }
4956
+ },
4957
+ newsletter: {
4958
+ bg: "#1e293b",
4959
+ color: "#f8fafc",
4960
+ border: "#334155",
4961
+ borderRadius: "0.5rem",
4962
+ padding: "2rem",
4963
+ titleColor: "#f8fafc",
4964
+ titleFontSize: "1.5rem",
4965
+ descColor: "#94a3b8",
4966
+ descFontSize: "1rem",
4967
+ inputBg: "#0f172a",
4968
+ inputBorder: "#475569",
4969
+ buttonBg: "#60a5fa",
4970
+ buttonColor: "#0f172a"
4971
+ }
4972
+ }
4973
+ };
4974
+
4975
+ // src/client/web/theme/theme-utils.ts
4976
+ function deepMerge(target, source) {
4977
+ const output = { ...target };
4978
+ for (const key in source) {
4979
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
4980
+ const sourceValue = source[key];
4981
+ const targetValue = target[key];
4982
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
4983
+ output[key] = deepMerge(
4984
+ targetValue,
4985
+ sourceValue
4986
+ );
4987
+ } else if (sourceValue !== void 0) {
4988
+ output[key] = sourceValue;
4989
+ }
4990
+ }
4991
+ }
4992
+ return output;
4993
+ }
4994
+ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
4995
+ const { colors: colors2 } = brand;
4996
+ const brandOverrides = {
4997
+ brand,
4998
+ colors: {
4999
+ brand: {
5000
+ primary: colors2.primary,
5001
+ secondary: colors2.secondary,
5002
+ accent: colors2.accent || colors2.primary,
5003
+ background: colors2.background || baseTheme.colors.background.default,
5004
+ foreground: colors2.foreground || baseTheme.colors.text.primary
5005
+ },
5006
+ semantic: {
5007
+ primary: colors2.primary,
5008
+ primaryHover: adjustColor(colors2.primary, -10),
5009
+ primaryActive: adjustColor(colors2.primary, -20),
5010
+ primaryDisabled: adjustColor(colors2.primary, 40),
5011
+ secondary: colors2.secondary,
5012
+ secondaryHover: adjustColor(colors2.secondary, -10),
5013
+ secondaryActive: adjustColor(colors2.secondary, -20),
5014
+ secondaryDisabled: adjustColor(colors2.secondary, 40),
5015
+ accent: colors2.accent || colors2.primary,
5016
+ accentHover: adjustColor(colors2.accent || colors2.primary, -10)
5017
+ }
5018
+ },
5019
+ components: {
5020
+ button: {
5021
+ bg: colors2.primary,
5022
+ bgHover: adjustColor(colors2.primary, -10),
5023
+ bgActive: adjustColor(colors2.primary, -20),
5024
+ variants: {
5025
+ primary: {
5026
+ bg: colors2.primary,
5027
+ bgHover: adjustColor(colors2.primary, -10)
5028
+ },
5029
+ secondary: {
5030
+ bg: colors2.secondary,
5031
+ bgHover: adjustColor(colors2.secondary, -10)
5032
+ }
5033
+ }
5034
+ },
5035
+ input: {
5036
+ borderFocus: colors2.primary
5037
+ },
5038
+ header: {
5039
+ navColorActive: colors2.primary
5040
+ },
5041
+ loader: {
5042
+ color: colors2.primary
5043
+ },
5044
+ newsletter: {
5045
+ buttonBg: colors2.primary
5046
+ }
5047
+ }
5048
+ };
5049
+ return deepMerge(baseTheme, brandOverrides);
5050
+ }
5051
+ function adjustColor(hex, percent) {
5052
+ hex = hex.replace(/^#/, "");
5053
+ let r = parseInt(hex.substring(0, 2), 16);
5054
+ let g = parseInt(hex.substring(2, 4), 16);
5055
+ let b = parseInt(hex.substring(4, 6), 16);
5056
+ r = Math.min(255, Math.max(0, r + r * percent / 100));
5057
+ g = Math.min(255, Math.max(0, g + g * percent / 100));
5058
+ b = Math.min(255, Math.max(0, b + b * percent / 100));
5059
+ const toHex = (n) => Math.round(n).toString(16).padStart(2, "0");
5060
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
5061
+ }
5062
+ function hexToRgba(hex, alpha = 1) {
5063
+ hex = hex.replace(/^#/, "");
5064
+ const r = parseInt(hex.substring(0, 2), 16);
5065
+ const g = parseInt(hex.substring(2, 4), 16);
5066
+ const b = parseInt(hex.substring(4, 6), 16);
5067
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
5068
+ }
5069
+ function getContrastColor(hex) {
5070
+ hex = hex.replace(/^#/, "");
5071
+ const r = parseInt(hex.substring(0, 2), 16);
5072
+ const g = parseInt(hex.substring(2, 4), 16);
5073
+ const b = parseInt(hex.substring(4, 6), 16);
5074
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
5075
+ return luminance > 0.5 ? "#000000" : "#ffffff";
5076
+ }
5077
+ function flattenToCssVars(obj, prefix = "--ec") {
5078
+ const result = {};
5079
+ function flatten(current, path2 = []) {
5080
+ for (const key in current) {
5081
+ if (Object.prototype.hasOwnProperty.call(current, key)) {
5082
+ const value = current[key];
5083
+ const newPath = [...path2, key];
5084
+ const varName = `${prefix}-${newPath.join("-")}`;
5085
+ if (value && typeof value === "object" && !Array.isArray(value)) {
5086
+ flatten(value, newPath);
5087
+ } else if (typeof value === "string" || typeof value === "number") {
5088
+ result[varName] = String(value);
5089
+ }
5090
+ }
5091
+ }
5092
+ }
5093
+ flatten(obj);
5094
+ return result;
5095
+ }
5096
+ function generateCssVars(theme, prefix = "--ec") {
5097
+ const cssVars = flattenToCssVars(theme, prefix);
5098
+ return Object.entries(cssVars).map(([key, value]) => `${key}: ${value};`).join("\n");
5099
+ }
5100
+ function injectCssVars(theme, prefix = "--ec") {
5101
+ if (typeof document === "undefined") return;
5102
+ const cssVars = flattenToCssVars(theme, prefix);
5103
+ const root = document.documentElement;
5104
+ for (const [key, value] of Object.entries(cssVars)) {
5105
+ root.style.setProperty(key, value);
5106
+ }
5107
+ }
5108
+ function removeCssVars(prefix = "--ec") {
5109
+ if (typeof document === "undefined") return;
5110
+ const root = document.documentElement;
5111
+ const style = root.style;
5112
+ for (let i = style.length - 1; i >= 0; i--) {
5113
+ const name = style[i];
5114
+ if (name.startsWith(prefix)) {
5115
+ root.style.removeProperty(name);
5116
+ }
5117
+ }
5118
+ }
5119
+ async function loadThemeFromUrl(url) {
5120
+ try {
5121
+ const response = await fetch(url, {
5122
+ headers: {
5123
+ Accept: "application/json"
5124
+ }
5125
+ });
5126
+ if (!response.ok) {
5127
+ console.error(`Failed to load theme from ${url}: ${response.status}`);
5128
+ return null;
5129
+ }
5130
+ const themeData = await response.json();
5131
+ return themeData;
5132
+ } catch (error) {
5133
+ console.error(`Error loading theme from ${url}:`, error);
5134
+ return null;
5135
+ }
5136
+ }
5137
+ async function createTheme(config = {}) {
5138
+ let lightTheme = { ...defaultLightTheme };
5139
+ let darkTheme = { ...defaultDarkTheme };
5140
+ if (config.themeUrl) {
5141
+ const urlTheme = await loadThemeFromUrl(config.themeUrl);
5142
+ if (urlTheme) {
5143
+ lightTheme = deepMerge(lightTheme, urlTheme);
5144
+ darkTheme = deepMerge(darkTheme, urlTheme);
5145
+ }
5146
+ }
5147
+ if (config.brandIdentity) {
5148
+ lightTheme = createThemeFromBrand(config.brandIdentity, lightTheme);
5149
+ darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
5150
+ }
5151
+ if (config.light) {
5152
+ lightTheme = deepMerge(lightTheme, config.light);
5153
+ }
5154
+ if (config.dark) {
5155
+ darkTheme = deepMerge(darkTheme, config.dark);
5156
+ }
5157
+ return { light: lightTheme, dark: darkTheme };
5158
+ }
5159
+ var DEFAULT_STORAGE_KEY = "ec-theme-mode";
5160
+ function saveThemeMode(mode, storageKey = DEFAULT_STORAGE_KEY) {
5161
+ if (typeof localStorage === "undefined") return;
5162
+ try {
5163
+ localStorage.setItem(storageKey, mode);
5164
+ } catch (error) {
5165
+ console.error("Failed to save theme mode:", error);
5166
+ }
5167
+ }
5168
+ function loadThemeMode(storageKey = DEFAULT_STORAGE_KEY) {
5169
+ if (typeof localStorage === "undefined") return null;
5170
+ try {
5171
+ const mode = localStorage.getItem(storageKey);
5172
+ if (mode === "light" || mode === "dark" || mode === "system") {
5173
+ return mode;
5174
+ }
5175
+ return null;
5176
+ } catch (error) {
5177
+ console.error("Failed to load theme mode:", error);
5178
+ return null;
5179
+ }
5180
+ }
5181
+ function getSystemColorScheme() {
5182
+ if (typeof window === "undefined") return "light";
5183
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5184
+ }
5185
+ function resolveThemeMode(mode) {
5186
+ if (mode === "system") {
5187
+ return getSystemColorScheme();
5188
+ }
5189
+ return mode;
5190
+ }
5191
+ var ThemeContext = react.createContext(null);
5192
+ function useTheme() {
5193
+ const context = react.useContext(ThemeContext);
5194
+ if (!context) {
5195
+ throw new Error("useTheme must be used within a ThemeProvider");
5196
+ }
5197
+ return context;
5198
+ }
5199
+ function ThemeProvider({
5200
+ children,
5201
+ config = {},
5202
+ initialTheme
5203
+ }) {
5204
+ const {
5205
+ defaultMode = "system",
5206
+ themeUrl,
5207
+ light: lightOverrides,
5208
+ dark: darkOverrides,
5209
+ brandIdentity,
5210
+ enableSystemTheme = true,
5211
+ persistTheme = true,
5212
+ storageKey = "ec-theme-mode",
5213
+ cssVarPrefix = "--ec"
5214
+ } = config;
5215
+ const [mode, setModeState] = react.useState(() => {
5216
+ if (persistTheme && typeof window !== "undefined") {
5217
+ const savedMode = loadThemeMode(storageKey);
5218
+ if (savedMode) return savedMode;
5219
+ }
5220
+ return defaultMode;
5221
+ });
5222
+ const [lightTheme, setLightTheme] = react.useState(() => {
5223
+ if (initialTheme && initialTheme.mode === "light") return initialTheme;
5224
+ let theme2 = defaultLightTheme;
5225
+ if (brandIdentity) {
5226
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5227
+ }
5228
+ if (lightOverrides) {
5229
+ theme2 = deepMerge(theme2, lightOverrides);
5230
+ }
5231
+ return theme2;
5232
+ });
5233
+ const [darkTheme, setDarkTheme] = react.useState(() => {
5234
+ if (initialTheme && initialTheme.mode === "dark") return initialTheme;
5235
+ let theme2 = defaultDarkTheme;
5236
+ if (brandIdentity) {
5237
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5238
+ }
5239
+ if (darkOverrides) {
5240
+ theme2 = deepMerge(theme2, darkOverrides);
5241
+ }
5242
+ return theme2;
5243
+ });
5244
+ const [isLoading, setIsLoading] = react.useState(!!themeUrl);
5245
+ const [error, setError] = react.useState(null);
5246
+ const resolvedMode = react.useMemo(() => resolveThemeMode(mode), [mode]);
5247
+ const theme = react.useMemo(
5248
+ () => resolvedMode === "dark" ? darkTheme : lightTheme,
5249
+ [resolvedMode, lightTheme, darkTheme]
5250
+ );
5251
+ const isDark = resolvedMode === "dark";
5252
+ const isLight = resolvedMode === "light";
5253
+ react.useEffect(() => {
5254
+ if (!themeUrl) return;
5255
+ setIsLoading(true);
5256
+ setError(null);
5257
+ loadThemeFromUrl(themeUrl).then((urlTheme) => {
5258
+ if (urlTheme) {
5259
+ setLightTheme((prev) => deepMerge(prev, urlTheme));
5260
+ setDarkTheme((prev) => deepMerge(prev, urlTheme));
5261
+ }
5262
+ }).catch((err) => {
5263
+ setError(err instanceof Error ? err.message : "Failed to load theme");
5264
+ }).finally(() => {
5265
+ setIsLoading(false);
5266
+ });
5267
+ }, [themeUrl]);
5268
+ react.useEffect(() => {
5269
+ if (typeof window !== "undefined") {
5270
+ injectCssVars(theme, cssVarPrefix);
5271
+ }
5272
+ }, [theme, cssVarPrefix]);
5273
+ react.useEffect(() => {
5274
+ if (typeof document !== "undefined") {
5275
+ document.documentElement.setAttribute("data-theme", resolvedMode);
5276
+ document.documentElement.style.colorScheme = resolvedMode;
5277
+ }
5278
+ }, [resolvedMode]);
5279
+ react.useEffect(() => {
5280
+ if (!enableSystemTheme || typeof window === "undefined") return;
5281
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
5282
+ const handleChange = () => {
5283
+ if (mode === "system") {
5284
+ setModeState("system");
5285
+ }
5286
+ };
5287
+ mediaQuery.addEventListener("change", handleChange);
5288
+ return () => mediaQuery.removeEventListener("change", handleChange);
5289
+ }, [mode, enableSystemTheme]);
5290
+ react.useEffect(() => {
5291
+ if (persistTheme && typeof window !== "undefined") {
5292
+ saveThemeMode(mode, storageKey);
5293
+ }
5294
+ }, [mode, persistTheme, storageKey]);
5295
+ const setMode = react.useCallback((newMode) => {
5296
+ setModeState(newMode);
5297
+ }, []);
5298
+ const toggleMode = react.useCallback(() => {
5299
+ setModeState((prev) => {
5300
+ const current = resolveThemeMode(prev);
5301
+ return current === "dark" ? "light" : "dark";
5302
+ });
5303
+ }, []);
5304
+ const updateTheme = react.useCallback((updates) => {
5305
+ setLightTheme((prev) => deepMerge(prev, updates));
5306
+ setDarkTheme((prev) => deepMerge(prev, updates));
5307
+ }, []);
5308
+ const resetTheme = react.useCallback(() => {
5309
+ let light = defaultLightTheme;
5310
+ let dark = defaultDarkTheme;
5311
+ if (brandIdentity) {
5312
+ light = createThemeFromBrand(brandIdentity, light);
5313
+ dark = createThemeFromBrand(brandIdentity, dark);
5314
+ }
5315
+ if (lightOverrides) {
5316
+ light = deepMerge(light, lightOverrides);
5317
+ }
5318
+ if (darkOverrides) {
5319
+ dark = deepMerge(dark, darkOverrides);
5320
+ }
5321
+ setLightTheme(light);
5322
+ setDarkTheme(dark);
5323
+ }, [brandIdentity, lightOverrides, darkOverrides]);
5324
+ const contextValue = react.useMemo(
5325
+ () => ({
5326
+ theme,
5327
+ mode,
5328
+ setMode,
5329
+ toggleMode,
5330
+ updateTheme,
5331
+ resetTheme,
5332
+ isDark,
5333
+ isLight,
5334
+ isLoading,
5335
+ error
5336
+ }),
5337
+ [theme, mode, setMode, toggleMode, updateTheme, resetTheme, isDark, isLight, isLoading, error]
5338
+ );
5339
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children });
5340
+ }
5341
+ function cssVar(path2, prefix = "--ec") {
5342
+ return `var(${prefix}-${path2.replace(/\./g, "-")})`;
5343
+ }
5344
+ function useThemeValue(selector) {
5345
+ const { theme } = useTheme();
5346
+ return selector(theme);
5347
+ }
5348
+ function ThemeToggle({
5349
+ className = "",
5350
+ size = 24,
5351
+ showLabel = false,
5352
+ lightLabel = "Light",
5353
+ darkLabel = "Dark"
5354
+ }) {
5355
+ const { isDark, toggleMode } = useTheme();
5356
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5357
+ "button",
5358
+ {
5359
+ type: "button",
5360
+ onClick: toggleMode,
5361
+ className: `ec-theme-toggle ${className}`,
5362
+ "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
5363
+ style: {
5364
+ background: "none",
5365
+ border: "none",
5366
+ cursor: "pointer",
5367
+ display: "inline-flex",
5368
+ alignItems: "center",
5369
+ gap: "0.5rem",
5370
+ padding: "0.5rem",
5371
+ borderRadius: "0.375rem",
5372
+ transition: "background-color 200ms ease-in-out"
5373
+ },
5374
+ children: [
5375
+ isDark ? (
5376
+ // Sun icon for dark mode (click to go light)
5377
+ /* @__PURE__ */ jsxRuntime.jsxs(
5378
+ "svg",
5379
+ {
5380
+ width: size,
5381
+ height: size,
5382
+ viewBox: "0 0 24 24",
5383
+ fill: "none",
5384
+ stroke: "currentColor",
5385
+ strokeWidth: "2",
5386
+ strokeLinecap: "round",
5387
+ strokeLinejoin: "round",
5388
+ children: [
5389
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }),
5390
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
5391
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
5392
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
5393
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
5394
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
5395
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
5396
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
5397
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
5398
+ ]
5399
+ }
5400
+ )
5401
+ ) : (
5402
+ // Moon icon for light mode (click to go dark)
5403
+ /* @__PURE__ */ jsxRuntime.jsx(
5404
+ "svg",
5405
+ {
5406
+ width: size,
5407
+ height: size,
5408
+ viewBox: "0 0 24 24",
5409
+ fill: "none",
5410
+ stroke: "currentColor",
5411
+ strokeWidth: "2",
5412
+ strokeLinecap: "round",
5413
+ strokeLinejoin: "round",
5414
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
5415
+ }
5416
+ )
5417
+ ),
5418
+ showLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isDark ? darkLabel : lightLabel })
5419
+ ]
5420
+ }
5421
+ );
5422
+ }
5423
+
5424
+ // src/client/web/astro/types.ts
5425
+ function dummyImage(width, height, text, bgColor = "cccccc", textColor = "969696") {
5426
+ const label = text ? `&text=${encodeURIComponent(text)}` : "";
5427
+ return `https://dummyimage.com/${width}x${height}/${bgColor}/${textColor}${label}`;
5428
+ }
5429
+ function loremIpsum(type = "paragraph", count = 1) {
5430
+ const words = [
5431
+ "lorem",
5432
+ "ipsum",
5433
+ "dolor",
5434
+ "sit",
5435
+ "amet",
5436
+ "consectetur",
5437
+ "adipiscing",
5438
+ "elit",
5439
+ "sed",
5440
+ "do",
5441
+ "eiusmod",
5442
+ "tempor",
5443
+ "incididunt",
5444
+ "ut",
5445
+ "labore",
5446
+ "et",
5447
+ "dolore",
5448
+ "magna",
5449
+ "aliqua",
5450
+ "enim",
5451
+ "ad",
5452
+ "minim",
5453
+ "veniam",
5454
+ "quis",
5455
+ "nostrud",
5456
+ "exercitation",
5457
+ "ullamco",
5458
+ "laboris",
5459
+ "nisi",
5460
+ "aliquip",
5461
+ "ex",
5462
+ "ea",
5463
+ "commodo",
5464
+ "consequat",
5465
+ "duis",
5466
+ "aute",
5467
+ "irure",
5468
+ "in",
5469
+ "reprehenderit",
5470
+ "voluptate",
5471
+ "velit",
5472
+ "esse",
5473
+ "cillum",
5474
+ "fugiat",
5475
+ "nulla",
5476
+ "pariatur",
5477
+ "excepteur",
5478
+ "sint",
5479
+ "occaecat",
5480
+ "cupidatat",
5481
+ "non",
5482
+ "proident",
5483
+ "sunt",
5484
+ "culpa",
5485
+ "qui",
5486
+ "officia",
5487
+ "deserunt",
5488
+ "mollit",
5489
+ "anim",
5490
+ "id",
5491
+ "est",
5492
+ "laborum"
5493
+ ];
5494
+ const getWords = (n) => {
5495
+ const result = [];
5496
+ for (let i = 0; i < n; i++) {
5497
+ result.push(words[Math.floor(Math.random() * words.length)]);
5498
+ }
5499
+ return result;
5500
+ };
5501
+ const capitalize2 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
5502
+ if (type === "word") {
5503
+ return getWords(count).join(" ");
5504
+ }
5505
+ if (type === "sentence") {
5506
+ const sentences = [];
5507
+ for (let i = 0; i < count; i++) {
5508
+ const sentence = capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".";
5509
+ sentences.push(sentence);
5510
+ }
5511
+ return sentences.join(" ");
5512
+ }
5513
+ const paragraphs = [];
5514
+ for (let i = 0; i < count; i++) {
5515
+ const sentences = [];
5516
+ const sentenceCount = Math.floor(Math.random() * 4) + 3;
5517
+ for (let j = 0; j < sentenceCount; j++) {
5518
+ sentences.push(capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".");
5519
+ }
5520
+ paragraphs.push(sentences.join(" "));
5521
+ }
5522
+ return paragraphs.join("\n\n");
5523
+ }
5524
+ var dummyHeaderData = {
5525
+ logo: dummyImage(120, 40, "Logo"),
5526
+ logoAlt: "Company Logo",
5527
+ navLinks: [
5528
+ { text: "Home", href: "/", active: true },
5529
+ { text: "About", href: "/about" },
5530
+ { text: "Services", href: "/services" },
5531
+ { text: "Blog", href: "/blog" },
5532
+ { text: "Contact", href: "/contact" }
5533
+ ],
5534
+ cta: {
5535
+ text: "Get Started",
5536
+ href: "/signup",
5537
+ variant: "primary"
5538
+ },
5539
+ sticky: true
5540
+ };
5541
+ var dummyFooterData = {
5542
+ logo: dummyImage(120, 40, "Logo"),
5543
+ logoAlt: "Company Logo",
5544
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.",
5545
+ columns: [
5546
+ {
5547
+ title: "Product",
5548
+ links: [
5549
+ { text: "Features", href: "/features" },
5550
+ { text: "Pricing", href: "/pricing" },
5551
+ { text: "Integrations", href: "/integrations" },
5552
+ { text: "API", href: "/api" }
5553
+ ]
5554
+ },
5555
+ {
5556
+ title: "Company",
5557
+ links: [
5558
+ { text: "About", href: "/about" },
5559
+ { text: "Blog", href: "/blog" },
5560
+ { text: "Careers", href: "/careers" },
5561
+ { text: "Contact", href: "/contact" }
5562
+ ]
5563
+ },
5564
+ {
5565
+ title: "Legal",
5566
+ links: [
5567
+ { text: "Privacy Policy", href: "/privacy" },
5568
+ { text: "Terms of Service", href: "/terms" },
5569
+ { text: "Cookie Policy", href: "/cookies" }
5570
+ ]
5571
+ }
5572
+ ],
5573
+ socialLinks: [
5574
+ { platform: "twitter", href: "https://twitter.com" },
5575
+ { platform: "facebook", href: "https://facebook.com" },
5576
+ { platform: "instagram", href: "https://instagram.com" },
5577
+ { platform: "linkedin", href: "https://linkedin.com" },
5578
+ { platform: "github", href: "https://github.com" }
5579
+ ],
5580
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Company Name. All rights reserved.`
5581
+ };
5582
+ var dummyBannerData = {
5583
+ title: "Build Something Amazing Today",
5584
+ subtitle: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5585
+ backgroundImage: dummyImage(1920, 800, "Hero+Background", "1e293b", "334155"),
5586
+ primaryCta: {
5587
+ text: "Get Started Free",
5588
+ href: "/signup",
5589
+ variant: "primary"
5590
+ },
5591
+ secondaryCta: {
5592
+ text: "Learn More",
5593
+ href: "/about",
5594
+ variant: "outline"
5595
+ },
5596
+ height: "lg",
5597
+ align: "center"
5598
+ };
5599
+ var dummyFeatures = [
5600
+ {
5601
+ title: "Lightning Fast",
5602
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
5603
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>'
5604
+ },
5605
+ {
5606
+ title: "Secure & Reliable",
5607
+ description: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5608
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" /></svg>'
5609
+ },
5610
+ {
5611
+ title: "Easy to Use",
5612
+ description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
5613
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /></svg>'
5614
+ }
5615
+ ];
5616
+ var dummyTestimonials = [
5617
+ {
5618
+ name: "John Doe",
5619
+ role: "CEO",
5620
+ company: "Tech Corp",
5621
+ avatar: dummyImage(80, 80, "JD", "3b82f6", "ffffff"),
5622
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
5623
+ rating: 5
5624
+ },
5625
+ {
5626
+ name: "Jane Smith",
5627
+ role: "CTO",
5628
+ company: "Startup Inc",
5629
+ avatar: dummyImage(80, 80, "JS", "10b981", "ffffff"),
5630
+ text: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
5631
+ rating: 5
5632
+ },
5633
+ {
5634
+ name: "Bob Wilson",
5635
+ role: "Product Manager",
5636
+ company: "Enterprise Co",
5637
+ avatar: dummyImage(80, 80, "BW", "f59e0b", "ffffff"),
5638
+ text: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
5639
+ rating: 4
5640
+ }
5641
+ ];
5642
+ var dummyPricingPlans = [
5643
+ {
5644
+ name: "Starter",
5645
+ description: "Perfect for individuals",
5646
+ price: "$9",
5647
+ period: "/month",
5648
+ features: [
5649
+ { text: "5 Projects", included: true },
5650
+ { text: "10GB Storage", included: true },
5651
+ { text: "Email Support", included: true },
5652
+ { text: "API Access", included: false },
5653
+ { text: "Custom Domain", included: false }
5654
+ ],
5655
+ ctaText: "Start Free Trial",
5656
+ ctaHref: "/signup?plan=starter"
5657
+ },
5658
+ {
5659
+ name: "Professional",
5660
+ description: "Best for growing teams",
5661
+ price: "$29",
5662
+ period: "/month",
5663
+ features: [
5664
+ { text: "Unlimited Projects", included: true },
5665
+ { text: "100GB Storage", included: true },
5666
+ { text: "Priority Support", included: true },
5667
+ { text: "API Access", included: true },
5668
+ { text: "Custom Domain", included: false }
5669
+ ],
5670
+ ctaText: "Start Free Trial",
5671
+ ctaHref: "/signup?plan=pro",
5672
+ popular: true,
5673
+ badge: "Most Popular"
5674
+ },
5675
+ {
5676
+ name: "Enterprise",
5677
+ description: "For large organizations",
5678
+ price: "$99",
5679
+ period: "/month",
5680
+ features: [
5681
+ { text: "Unlimited Projects", included: true },
5682
+ { text: "Unlimited Storage", included: true },
5683
+ { text: "24/7 Support", included: true },
5684
+ { text: "API Access", included: true },
5685
+ { text: "Custom Domain", included: true }
5686
+ ],
5687
+ ctaText: "Contact Sales",
5688
+ ctaHref: "/contact?plan=enterprise"
5689
+ }
5690
+ ];
5691
+ var dummyFaqItems = [
5692
+ {
5693
+ question: "What is your refund policy?",
5694
+ answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
5695
+ },
5696
+ {
5697
+ question: "How do I cancel my subscription?",
5698
+ answer: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
5699
+ },
5700
+ {
5701
+ question: "Can I change my plan later?",
5702
+ answer: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
5703
+ },
5704
+ {
5705
+ question: "Do you offer discounts for non-profits?",
5706
+ answer: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
5707
+ }
5708
+ ];
5709
+
5710
+ // src/client/web/forms/types.ts
5711
+ var VALIDATION_MESSAGES = {
5712
+ required: "This field is required",
5713
+ email: "Please enter a valid email address",
5714
+ phone: "Please enter a valid phone number",
5715
+ minLength: (min) => `Must be at least ${min} characters`,
5716
+ maxLength: (max) => `Must be no more than ${max} characters`,
5717
+ passwordMatch: "Passwords must match",
5718
+ acceptTerms: "You must accept the terms and conditions",
5719
+ passwordUppercase: "Password must contain at least one uppercase letter",
5720
+ passwordLowercase: "Password must contain at least one lowercase letter",
5721
+ passwordNumber: "Password must contain at least one number",
5722
+ passwordSpecial: "Password must contain at least one special character"
5723
+ };
5724
+ var contactFormSchema = Yup__namespace.object().shape({
5725
+ name: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(100, VALIDATION_MESSAGES.maxLength(100)),
5726
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5727
+ phone: Yup__namespace.string().matches(
5728
+ /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
5729
+ VALIDATION_MESSAGES.phone
5730
+ ).nullable(),
5731
+ subject: Yup__namespace.string().max(200, VALIDATION_MESSAGES.maxLength(200)).nullable(),
5732
+ message: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(10, VALIDATION_MESSAGES.minLength(10)).max(2e3, VALIDATION_MESSAGES.maxLength(2e3))
5733
+ });
5734
+ var newsletterFormSchema = Yup__namespace.object().shape({
5735
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5736
+ firstName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable(),
5737
+ lastName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable()
5738
+ });
5739
+ var loginFormSchema = Yup__namespace.object().shape({
5740
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5741
+ password: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(8, VALIDATION_MESSAGES.minLength(8)),
5742
+ rememberMe: Yup__namespace.boolean()
5743
+ });
5744
+ function createRegisterFormSchema(requirements = {}) {
5745
+ const {
5746
+ minLength = 8,
5747
+ requireUppercase = true,
5748
+ requireLowercase = true,
5749
+ requireNumber = true,
5750
+ requireSpecial = false
5751
+ } = requirements;
5752
+ let passwordSchema = Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(minLength, VALIDATION_MESSAGES.minLength(minLength));
5753
+ if (requireUppercase) {
5754
+ passwordSchema = passwordSchema.matches(
5755
+ /[A-Z]/,
5756
+ VALIDATION_MESSAGES.passwordUppercase
5757
+ );
5758
+ }
5759
+ if (requireLowercase) {
5760
+ passwordSchema = passwordSchema.matches(
5761
+ /[a-z]/,
5762
+ VALIDATION_MESSAGES.passwordLowercase
5763
+ );
5764
+ }
5765
+ if (requireNumber) {
5766
+ passwordSchema = passwordSchema.matches(
5767
+ /[0-9]/,
5768
+ VALIDATION_MESSAGES.passwordNumber
5769
+ );
5770
+ }
5771
+ if (requireSpecial) {
5772
+ passwordSchema = passwordSchema.matches(
5773
+ /[!@#$%^&*(),.?":{}|<>]/,
5774
+ VALIDATION_MESSAGES.passwordSpecial
5775
+ );
5776
+ }
5777
+ return Yup__namespace.object().shape({
5778
+ firstName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
5779
+ lastName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
5780
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
5781
+ password: passwordSchema,
5782
+ confirmPassword: Yup__namespace.string().required(VALIDATION_MESSAGES.required).oneOf([Yup__namespace.ref("password")], VALIDATION_MESSAGES.passwordMatch),
5783
+ acceptTerms: Yup__namespace.boolean().oneOf([true], VALIDATION_MESSAGES.acceptTerms)
5784
+ });
5785
+ }
5786
+ var registerFormSchema = createRegisterFormSchema();
5787
+ var defaultInitialValues = {
5788
+ name: "",
5789
+ email: "",
5790
+ phone: "",
5791
+ subject: "",
5792
+ message: ""
5793
+ };
5794
+ var defaultSubjectOptions = [
5795
+ "General Inquiry",
5796
+ "Support Request",
5797
+ "Sales Question",
5798
+ "Partnership",
5799
+ "Feedback",
5800
+ "Other"
5801
+ ];
5802
+ function ContactForm({
5803
+ actionUrl,
5804
+ onSubmit,
5805
+ initialValues,
5806
+ showPhone = true,
5807
+ showSubject = true,
5808
+ subjectOptions = defaultSubjectOptions,
5809
+ submitText = "Send Message",
5810
+ successMessage = "Thank you! Your message has been sent successfully.",
5811
+ className = "",
5812
+ formClass = "",
5813
+ inputClass = "",
5814
+ labelClass = "",
5815
+ buttonClass = "",
5816
+ errorClass = ""
5817
+ }) {
5818
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
5819
+ const [submitMessage, setSubmitMessage] = react.useState("");
5820
+ const mergedInitialValues = {
5821
+ ...defaultInitialValues,
5822
+ ...initialValues
5823
+ };
5824
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
5825
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
5826
+ const baseErrorClass = "text-sm text-red-600 mt-1";
5827
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
5828
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
5829
+ try {
5830
+ let result;
5831
+ if (onSubmit) {
5832
+ result = await onSubmit(values);
5833
+ } else if (actionUrl) {
5834
+ const response = await fetch(actionUrl, {
5835
+ method: "POST",
5836
+ headers: { "Content-Type": "application/json" },
5837
+ body: JSON.stringify(values)
5838
+ });
5839
+ result = await response.json();
5840
+ } else {
5841
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
5842
+ result = { success: true };
5843
+ }
5844
+ if (result.success) {
5845
+ setSubmitStatus("success");
5846
+ setSubmitMessage(result.message || successMessage);
5847
+ resetForm();
5848
+ } else {
5849
+ setSubmitStatus("error");
5850
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
5851
+ }
5852
+ } catch (error) {
5853
+ setSubmitStatus("error");
5854
+ setSubmitMessage("An error occurred. Please try again later.");
5855
+ } finally {
5856
+ setSubmitting(false);
5857
+ }
5858
+ };
5859
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-contact-form ${className}`, children: submitStatus === "success" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
5860
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 text-green-500 mx-auto mb-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
5861
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
5862
+ /* @__PURE__ */ jsxRuntime.jsx(
5863
+ "button",
5864
+ {
5865
+ type: "button",
5866
+ onClick: () => setSubmitStatus("idle"),
5867
+ className: "mt-4 text-green-600 hover:text-green-700 text-sm font-medium",
5868
+ children: "Send another message"
5869
+ }
5870
+ )
5871
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
5872
+ formik.Formik,
5873
+ {
5874
+ initialValues: mergedInitialValues,
5875
+ validationSchema: contactFormSchema,
5876
+ onSubmit: handleSubmit,
5877
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
5878
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5879
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-name", className: `${baseLabelClass} ${labelClass}`, children: [
5880
+ "Name ",
5881
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5882
+ ] }),
5883
+ /* @__PURE__ */ jsxRuntime.jsx(
5884
+ formik.Field,
5885
+ {
5886
+ type: "text",
5887
+ id: "contact-name",
5888
+ name: "name",
5889
+ placeholder: "John Doe",
5890
+ className: `${baseInputClass} ${inputClass} ${errors.name && touched.name ? "border-red-500 focus:ring-red-500" : ""}`
5891
+ }
5892
+ ),
5893
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "name", component: "p", className: `${baseErrorClass} ${errorClass}` })
5894
+ ] }),
5895
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5896
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-email", className: `${baseLabelClass} ${labelClass}`, children: [
5897
+ "Email ",
5898
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5899
+ ] }),
5900
+ /* @__PURE__ */ jsxRuntime.jsx(
5901
+ formik.Field,
5902
+ {
5903
+ type: "email",
5904
+ id: "contact-email",
5905
+ name: "email",
5906
+ placeholder: "john@example.com",
5907
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
5908
+ }
5909
+ ),
5910
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: `${baseErrorClass} ${errorClass}` })
5911
+ ] }),
5912
+ showPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5913
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-phone", className: `${baseLabelClass} ${labelClass}`, children: "Phone" }),
5914
+ /* @__PURE__ */ jsxRuntime.jsx(
5915
+ formik.Field,
5916
+ {
5917
+ type: "tel",
5918
+ id: "contact-phone",
5919
+ name: "phone",
5920
+ placeholder: "+1 (555) 000-0000",
5921
+ className: `${baseInputClass} ${inputClass} ${errors.phone && touched.phone ? "border-red-500 focus:ring-red-500" : ""}`
5922
+ }
5923
+ ),
5924
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "phone", component: "p", className: `${baseErrorClass} ${errorClass}` })
5925
+ ] }),
5926
+ showSubject && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5927
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-subject", className: `${baseLabelClass} ${labelClass}`, children: "Subject" }),
5928
+ /* @__PURE__ */ jsxRuntime.jsxs(
5929
+ formik.Field,
5930
+ {
5931
+ as: "select",
5932
+ id: "contact-subject",
5933
+ name: "subject",
5934
+ className: `${baseInputClass} ${inputClass}`,
5935
+ children: [
5936
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select a subject..." }),
5937
+ subjectOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: option }, option))
5938
+ ]
5939
+ }
5940
+ ),
5941
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "subject", component: "p", className: `${baseErrorClass} ${errorClass}` })
5942
+ ] }),
5943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5944
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-message", className: `${baseLabelClass} ${labelClass}`, children: [
5945
+ "Message ",
5946
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
5947
+ ] }),
5948
+ /* @__PURE__ */ jsxRuntime.jsx(
5949
+ formik.Field,
5950
+ {
5951
+ as: "textarea",
5952
+ id: "contact-message",
5953
+ name: "message",
5954
+ rows: 5,
5955
+ placeholder: "Your message...",
5956
+ className: `${baseInputClass} ${inputClass} resize-none ${errors.message && touched.message ? "border-red-500 focus:ring-red-500" : ""}`
5957
+ }
5958
+ ),
5959
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "message", component: "p", className: `${baseErrorClass} ${errorClass}` })
5960
+ ] }),
5961
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
5962
+ /* @__PURE__ */ jsxRuntime.jsx(
5963
+ "button",
5964
+ {
5965
+ type: "submit",
5966
+ disabled: isSubmitting,
5967
+ className: `${baseButtonClass} ${buttonClass}`,
5968
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
5969
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
5970
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5971
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
5972
+ ] }),
5973
+ "Sending..."
5974
+ ] }) : submitText
5975
+ }
5976
+ )
5977
+ ] })
5978
+ }
5979
+ ) });
5980
+ }
5981
+ var defaultInitialValues2 = {
5982
+ email: "",
5983
+ firstName: "",
5984
+ lastName: ""
5985
+ };
5986
+ function NewsletterForm({
5987
+ actionUrl,
5988
+ onSubmit,
5989
+ initialValues,
5990
+ showName = false,
5991
+ placeholder = "Enter your email",
5992
+ submitText = "Subscribe",
5993
+ successMessage = "Thank you for subscribing!",
5994
+ layout = "inline",
5995
+ className = "",
5996
+ formClass = "",
5997
+ inputClass = "",
5998
+ buttonClass = ""
5999
+ }) {
6000
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6001
+ const [submitMessage, setSubmitMessage] = react.useState("");
6002
+ const mergedInitialValues = {
6003
+ ...defaultInitialValues2,
6004
+ ...initialValues
6005
+ };
6006
+ const baseInputClass = "px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
6007
+ const baseButtonClass = "px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
6008
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
6009
+ try {
6010
+ let result;
6011
+ if (onSubmit) {
6012
+ result = await onSubmit(values);
6013
+ } else if (actionUrl) {
6014
+ const response = await fetch(actionUrl, {
6015
+ method: "POST",
6016
+ headers: { "Content-Type": "application/json" },
6017
+ body: JSON.stringify(values)
6018
+ });
6019
+ result = await response.json();
6020
+ } else {
6021
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6022
+ result = { success: true };
6023
+ }
6024
+ if (result.success) {
6025
+ setSubmitStatus("success");
6026
+ setSubmitMessage(result.message || successMessage);
6027
+ resetForm();
6028
+ } else {
6029
+ setSubmitStatus("error");
6030
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
6031
+ }
6032
+ } catch (error) {
6033
+ setSubmitStatus("error");
6034
+ setSubmitMessage("An error occurred. Please try again later.");
6035
+ } finally {
6036
+ setSubmitting(false);
6037
+ }
6038
+ };
6039
+ if (submitStatus === "success") {
6040
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-newsletter-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 bg-green-50 border border-green-200 rounded-lg text-center", children: [
6041
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6042
+ /* @__PURE__ */ jsxRuntime.jsx(
6043
+ "button",
6044
+ {
6045
+ type: "button",
6046
+ onClick: () => setSubmitStatus("idle"),
6047
+ className: "mt-2 text-green-600 hover:text-green-700 text-sm",
6048
+ children: "Subscribe another email"
6049
+ }
6050
+ )
6051
+ ] }) });
6052
+ }
6053
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `ec-newsletter-form ${className}`, children: [
6054
+ /* @__PURE__ */ jsxRuntime.jsx(
6055
+ formik.Formik,
6056
+ {
6057
+ initialValues: mergedInitialValues,
6058
+ validationSchema: newsletterFormSchema,
6059
+ onSubmit: handleSubmit,
6060
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(
6061
+ formik.Form,
6062
+ {
6063
+ className: `${layout === "inline" ? "flex flex-col sm:flex-row gap-3" : "space-y-4"} ${formClass}`,
6064
+ noValidate: true,
6065
+ children: [
6066
+ showName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex gap-3 flex-1" : "grid grid-cols-2 gap-4", children: [
6067
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
6068
+ /* @__PURE__ */ jsxRuntime.jsx(
6069
+ formik.Field,
6070
+ {
6071
+ type: "text",
6072
+ name: "firstName",
6073
+ placeholder: "First name",
6074
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500" : ""}`
6075
+ }
6076
+ ),
6077
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: "text-sm text-red-600 mt-1" })
6078
+ ] }),
6079
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
6080
+ /* @__PURE__ */ jsxRuntime.jsx(
6081
+ formik.Field,
6082
+ {
6083
+ type: "text",
6084
+ name: "lastName",
6085
+ placeholder: "Last name",
6086
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500" : ""}`
6087
+ }
6088
+ ),
6089
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: "text-sm text-red-600 mt-1" })
6090
+ ] })
6091
+ ] }),
6092
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex-1" : "", children: [
6093
+ /* @__PURE__ */ jsxRuntime.jsx(
6094
+ formik.Field,
6095
+ {
6096
+ type: "email",
6097
+ name: "email",
6098
+ placeholder,
6099
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500" : ""}`
6100
+ }
6101
+ ),
6102
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: "text-sm text-red-600 mt-1" })
6103
+ ] }),
6104
+ /* @__PURE__ */ jsxRuntime.jsx(
6105
+ "button",
6106
+ {
6107
+ type: "submit",
6108
+ disabled: isSubmitting,
6109
+ className: `${baseButtonClass} ${buttonClass} ${layout === "stacked" ? "w-full" : ""}`,
6110
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6111
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6112
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6113
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
6114
+ ] }),
6115
+ "Subscribing..."
6116
+ ] }) : submitText
6117
+ }
6118
+ ),
6119
+ layout === "inline" && errors.email && touched.email && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full sm:w-auto", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600", children: errors.email }) })
6120
+ ]
6121
+ }
6122
+ )
6123
+ }
6124
+ ),
6125
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) })
6126
+ ] });
6127
+ }
6128
+ var defaultInitialValues3 = {
6129
+ email: "",
6130
+ password: "",
6131
+ rememberMe: false
6132
+ };
6133
+ function LoginForm({
6134
+ actionUrl,
6135
+ onSubmit,
6136
+ initialValues,
6137
+ showRememberMe = true,
6138
+ forgotPasswordLink = "/forgot-password",
6139
+ registerLink = "/register",
6140
+ submitText = "Sign In",
6141
+ successRedirect,
6142
+ className = "",
6143
+ formClass = "",
6144
+ inputClass = "",
6145
+ buttonClass = ""
6146
+ }) {
6147
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6148
+ const [submitMessage, setSubmitMessage] = react.useState("");
6149
+ const [showPassword, setShowPassword] = react.useState(false);
6150
+ const mergedInitialValues = {
6151
+ ...defaultInitialValues3,
6152
+ ...initialValues
6153
+ };
6154
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
6155
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6156
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6157
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
6158
+ const handleSubmit = async (values, { setSubmitting }) => {
6159
+ try {
6160
+ let result;
6161
+ if (onSubmit) {
6162
+ result = await onSubmit(values);
6163
+ } else if (actionUrl) {
6164
+ const response = await fetch(actionUrl, {
6165
+ method: "POST",
6166
+ headers: { "Content-Type": "application/json" },
6167
+ body: JSON.stringify(values)
6168
+ });
6169
+ result = await response.json();
6170
+ } else {
6171
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6172
+ result = { success: true };
6173
+ }
6174
+ if (result.success) {
6175
+ setSubmitStatus("success");
6176
+ setSubmitMessage(result.message || "Login successful!");
6177
+ if (successRedirect && typeof window !== "undefined") {
6178
+ window.location.href = successRedirect;
6179
+ }
6180
+ } else {
6181
+ setSubmitStatus("error");
6182
+ setSubmitMessage(result.message || "Invalid email or password.");
6183
+ }
6184
+ } catch (error) {
6185
+ setSubmitStatus("error");
6186
+ setSubmitMessage("An error occurred. Please try again later.");
6187
+ } finally {
6188
+ setSubmitting(false);
6189
+ }
6190
+ };
6191
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-login-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
6192
+ formik.Formik,
6193
+ {
6194
+ initialValues: mergedInitialValues,
6195
+ validationSchema: loginFormSchema,
6196
+ onSubmit: handleSubmit,
6197
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6198
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6199
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-email", className: baseLabelClass, children: "Email" }),
6200
+ /* @__PURE__ */ jsxRuntime.jsx(
6201
+ formik.Field,
6202
+ {
6203
+ type: "email",
6204
+ id: "login-email",
6205
+ name: "email",
6206
+ placeholder: "you@example.com",
6207
+ autoComplete: "email",
6208
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6209
+ }
6210
+ ),
6211
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
6212
+ ] }),
6213
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6214
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-password", className: baseLabelClass, children: "Password" }),
6215
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6216
+ /* @__PURE__ */ jsxRuntime.jsx(
6217
+ formik.Field,
6218
+ {
6219
+ type: showPassword ? "text" : "password",
6220
+ id: "login-password",
6221
+ name: "password",
6222
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6223
+ autoComplete: "current-password",
6224
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
6225
+ }
6226
+ ),
6227
+ /* @__PURE__ */ jsxRuntime.jsx(
6228
+ "button",
6229
+ {
6230
+ type: "button",
6231
+ onClick: () => setShowPassword(!showPassword),
6232
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6233
+ tabIndex: -1,
6234
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6235
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6236
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
6237
+ ] })
6238
+ }
6239
+ )
6240
+ ] }),
6241
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass })
6242
+ ] }),
6243
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
6244
+ showRememberMe && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
6245
+ /* @__PURE__ */ jsxRuntime.jsx(
6246
+ formik.Field,
6247
+ {
6248
+ type: "checkbox",
6249
+ name: "rememberMe",
6250
+ className: "w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
6251
+ }
6252
+ ),
6253
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-600", children: "Remember me" })
6254
+ ] }),
6255
+ forgotPasswordLink && /* @__PURE__ */ jsxRuntime.jsx(
6256
+ "a",
6257
+ {
6258
+ href: forgotPasswordLink,
6259
+ className: "text-sm text-blue-600 hover:text-blue-700 font-medium",
6260
+ children: "Forgot password?"
6261
+ }
6262
+ )
6263
+ ] }),
6264
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
6265
+ /* @__PURE__ */ jsxRuntime.jsx(
6266
+ "button",
6267
+ {
6268
+ type: "submit",
6269
+ disabled: isSubmitting,
6270
+ className: `${baseButtonClass} ${buttonClass}`,
6271
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6272
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6273
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6274
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
6275
+ ] }),
6276
+ "Signing in..."
6277
+ ] }) : submitText
6278
+ }
6279
+ ),
6280
+ registerLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
6281
+ "Don't have an account?",
6282
+ " ",
6283
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: registerLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign up" })
6284
+ ] })
6285
+ ] })
6286
+ }
6287
+ ) });
6288
+ }
6289
+ var defaultInitialValues4 = {
6290
+ firstName: "",
6291
+ lastName: "",
6292
+ email: "",
6293
+ password: "",
6294
+ confirmPassword: "",
6295
+ acceptTerms: false
6296
+ };
6297
+ function RegisterForm({
6298
+ actionUrl,
6299
+ onSubmit,
6300
+ initialValues,
6301
+ termsLink = "/terms",
6302
+ privacyLink = "/privacy",
6303
+ loginLink = "/login",
6304
+ submitText = "Create Account",
6305
+ successRedirect,
6306
+ passwordRequirements = {
6307
+ minLength: 8,
6308
+ requireUppercase: true,
6309
+ requireLowercase: true,
6310
+ requireNumber: true,
6311
+ requireSpecial: false
6312
+ },
6313
+ className = "",
6314
+ formClass = "",
6315
+ inputClass = "",
6316
+ buttonClass = ""
6317
+ }) {
6318
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6319
+ const [submitMessage, setSubmitMessage] = react.useState("");
6320
+ const [showPassword, setShowPassword] = react.useState(false);
6321
+ const [showConfirmPassword, setShowConfirmPassword] = react.useState(false);
6322
+ const mergedInitialValues = {
6323
+ ...defaultInitialValues4,
6324
+ ...initialValues
6325
+ };
6326
+ const validationSchema = createRegisterFormSchema(passwordRequirements);
6327
+ const baseInputClass = "w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors";
6328
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6329
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6330
+ const baseButtonClass = "w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed";
6331
+ const handleSubmit = async (values, { setSubmitting }) => {
6332
+ try {
6333
+ let result;
6334
+ if (onSubmit) {
6335
+ result = await onSubmit(values);
6336
+ } else if (actionUrl) {
6337
+ const response = await fetch(actionUrl, {
6338
+ method: "POST",
6339
+ headers: { "Content-Type": "application/json" },
6340
+ body: JSON.stringify(values)
6341
+ });
6342
+ result = await response.json();
6343
+ } else {
6344
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6345
+ result = { success: true };
6346
+ }
6347
+ if (result.success) {
6348
+ setSubmitStatus("success");
6349
+ setSubmitMessage(result.message || "Account created successfully!");
6350
+ if (successRedirect && typeof window !== "undefined") {
6351
+ window.location.href = successRedirect;
6352
+ }
6353
+ } else {
6354
+ setSubmitStatus("error");
6355
+ setSubmitMessage(result.message || "Registration failed. Please try again.");
6356
+ }
6357
+ } catch (error) {
6358
+ setSubmitStatus("error");
6359
+ setSubmitMessage("An error occurred. Please try again later.");
6360
+ } finally {
6361
+ setSubmitting(false);
6362
+ }
6363
+ };
6364
+ if (submitStatus === "success") {
6365
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 bg-green-50 border border-green-200 rounded-lg text-center", children: [
6366
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-12 h-12 text-green-500 mx-auto mb-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
6367
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6368
+ loginLink && /* @__PURE__ */ jsxRuntime.jsx(
6369
+ "a",
6370
+ {
6371
+ href: loginLink,
6372
+ className: "inline-block mt-4 text-green-600 hover:text-green-700 font-medium",
6373
+ children: "Sign in to your account"
6374
+ }
6375
+ )
6376
+ ] }) });
6377
+ }
6378
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
6379
+ formik.Formik,
6380
+ {
6381
+ initialValues: mergedInitialValues,
6382
+ validationSchema,
6383
+ onSubmit: handleSubmit,
6384
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
6386
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6387
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-firstName", className: baseLabelClass, children: [
6388
+ "First Name ",
6389
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6390
+ ] }),
6391
+ /* @__PURE__ */ jsxRuntime.jsx(
6392
+ formik.Field,
6393
+ {
6394
+ type: "text",
6395
+ id: "register-firstName",
6396
+ name: "firstName",
6397
+ placeholder: "John",
6398
+ autoComplete: "given-name",
6399
+ className: `${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500 focus:ring-red-500" : ""}`
6400
+ }
6401
+ ),
6402
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: baseErrorClass })
6403
+ ] }),
6404
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6405
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-lastName", className: baseLabelClass, children: [
6406
+ "Last Name ",
6407
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6408
+ ] }),
6409
+ /* @__PURE__ */ jsxRuntime.jsx(
6410
+ formik.Field,
6411
+ {
6412
+ type: "text",
6413
+ id: "register-lastName",
6414
+ name: "lastName",
6415
+ placeholder: "Doe",
6416
+ autoComplete: "family-name",
6417
+ className: `${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500 focus:ring-red-500" : ""}`
6418
+ }
6419
+ ),
6420
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: baseErrorClass })
6421
+ ] })
6422
+ ] }),
6423
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6424
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-email", className: baseLabelClass, children: [
6425
+ "Email ",
6426
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6427
+ ] }),
6428
+ /* @__PURE__ */ jsxRuntime.jsx(
6429
+ formik.Field,
6430
+ {
6431
+ type: "email",
6432
+ id: "register-email",
6433
+ name: "email",
6434
+ placeholder: "you@example.com",
6435
+ autoComplete: "email",
6436
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6437
+ }
6438
+ ),
6439
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
6440
+ ] }),
6441
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6442
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-password", className: baseLabelClass, children: [
6443
+ "Password ",
6444
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6445
+ ] }),
6446
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6447
+ /* @__PURE__ */ jsxRuntime.jsx(
6448
+ formik.Field,
6449
+ {
6450
+ type: showPassword ? "text" : "password",
6451
+ id: "register-password",
6452
+ name: "password",
6453
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6454
+ autoComplete: "new-password",
6455
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
6456
+ }
6457
+ ),
6458
+ /* @__PURE__ */ jsxRuntime.jsx(
6459
+ "button",
6460
+ {
6461
+ type: "button",
6462
+ onClick: () => setShowPassword(!showPassword),
6463
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6464
+ tabIndex: -1,
6465
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6466
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6467
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
6468
+ ] })
6469
+ }
6470
+ )
6471
+ ] }),
6472
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass }),
6473
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
6474
+ "Min ",
6475
+ passwordRequirements.minLength,
6476
+ " characters",
6477
+ passwordRequirements.requireUppercase && ", uppercase",
6478
+ passwordRequirements.requireLowercase && ", lowercase",
6479
+ passwordRequirements.requireNumber && ", number",
6480
+ passwordRequirements.requireSpecial && ", special character"
6481
+ ] })
6482
+ ] }),
6483
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6484
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-confirmPassword", className: baseLabelClass, children: [
6485
+ "Confirm Password ",
6486
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6487
+ ] }),
6488
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6489
+ /* @__PURE__ */ jsxRuntime.jsx(
6490
+ formik.Field,
6491
+ {
6492
+ type: showConfirmPassword ? "text" : "password",
6493
+ id: "register-confirmPassword",
6494
+ name: "confirmPassword",
6495
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6496
+ autoComplete: "new-password",
6497
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.confirmPassword && touched.confirmPassword ? "border-red-500 focus:ring-red-500" : ""}`
6498
+ }
6499
+ ),
6500
+ /* @__PURE__ */ jsxRuntime.jsx(
6501
+ "button",
6502
+ {
6503
+ type: "button",
6504
+ onClick: () => setShowConfirmPassword(!showConfirmPassword),
6505
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6506
+ tabIndex: -1,
6507
+ children: showConfirmPassword ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
6508
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6509
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
6510
+ ] })
6511
+ }
6512
+ )
6513
+ ] }),
6514
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "confirmPassword", component: "p", className: baseErrorClass })
6515
+ ] }),
6516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6517
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
6518
+ /* @__PURE__ */ jsxRuntime.jsx(
6519
+ formik.Field,
6520
+ {
6521
+ type: "checkbox",
6522
+ name: "acceptTerms",
6523
+ className: "w-4 h-4 mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
6524
+ }
6525
+ ),
6526
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600", children: [
6527
+ "I agree to the",
6528
+ " ",
6529
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: termsLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }),
6530
+ " ",
6531
+ "and",
6532
+ " ",
6533
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: privacyLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }),
6534
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: " *" })
6535
+ ] })
6536
+ ] }),
6537
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "acceptTerms", component: "p", className: baseErrorClass })
6538
+ ] }),
6539
+ submitStatus === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: submitMessage }) }),
6540
+ /* @__PURE__ */ jsxRuntime.jsx(
6541
+ "button",
6542
+ {
6543
+ type: "submit",
6544
+ disabled: isSubmitting,
6545
+ className: `${baseButtonClass} ${buttonClass}`,
6546
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6547
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6548
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6549
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
6550
+ ] }),
6551
+ "Creating account..."
6552
+ ] }) : submitText
6553
+ }
6554
+ ),
6555
+ loginLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
6556
+ "Already have an account?",
6557
+ " ",
6558
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: loginLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign in" })
6559
+ ] })
6560
+ ] })
6561
+ }
6562
+ ) });
6563
+ }
6564
+
3891
6565
  // src/shared/index.ts
3892
6566
  var shared_exports = {};
3893
6567
  __export(shared_exports, {
@@ -3921,7 +6595,7 @@ __export(shared_exports, {
3921
6595
  THEME: () => THEME,
3922
6596
  TOKEN_TYPES: () => TOKEN_TYPES,
3923
6597
  USER_STATUS: () => USER_STATUS,
3924
- VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
6598
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES2,
3925
6599
  VALIDATION_PATTERNS: () => VALIDATION_PATTERNS,
3926
6600
  VALIDATION_RULES: () => VALIDATION_RULES,
3927
6601
  VISIBILITY: () => VISIBILITY,
@@ -4844,7 +7518,7 @@ var isValidUsername = (username) => {
4844
7518
  var isValidSlug = (slug) => {
4845
7519
  return VALIDATION_PATTERNS.SLUG.test(slug);
4846
7520
  };
4847
- var VALIDATION_MESSAGES = {
7521
+ var VALIDATION_MESSAGES2 = {
4848
7522
  // Required fields
4849
7523
  REQUIRED: "This field is required",
4850
7524
  REQUIRED_FIELD: (field) => `${field} is required`,
@@ -4885,17 +7559,17 @@ var VALIDATION_MESSAGES = {
4885
7559
  var VALIDATION_RULES = {
4886
7560
  email: {
4887
7561
  pattern: VALIDATION_PATTERNS.EMAIL,
4888
- message: VALIDATION_MESSAGES.EMAIL_INVALID
7562
+ message: VALIDATION_MESSAGES2.EMAIL_INVALID
4889
7563
  },
4890
7564
  password: {
4891
7565
  minLength: 8,
4892
7566
  pattern: VALIDATION_PATTERNS.PASSWORD_MEDIUM,
4893
- message: VALIDATION_MESSAGES.PASSWORD_MEDIUM
7567
+ message: VALIDATION_MESSAGES2.PASSWORD_MEDIUM
4894
7568
  },
4895
7569
  passwordStrong: {
4896
7570
  minLength: 8,
4897
7571
  pattern: VALIDATION_PATTERNS.PASSWORD_STRONG,
4898
- message: VALIDATION_MESSAGES.PASSWORD_STRONG
7572
+ message: VALIDATION_MESSAGES2.PASSWORD_STRONG
4899
7573
  },
4900
7574
  name: {
4901
7575
  minLength: 2,
@@ -4905,15 +7579,15 @@ var VALIDATION_RULES = {
4905
7579
  minLength: 3,
4906
7580
  maxLength: 30,
4907
7581
  pattern: VALIDATION_PATTERNS.USERNAME,
4908
- message: VALIDATION_MESSAGES.USERNAME_INVALID
7582
+ message: VALIDATION_MESSAGES2.USERNAME_INVALID
4909
7583
  },
4910
7584
  phone: {
4911
7585
  pattern: VALIDATION_PATTERNS.PHONE_INTERNATIONAL,
4912
- message: VALIDATION_MESSAGES.PHONE_INVALID
7586
+ message: VALIDATION_MESSAGES2.PHONE_INVALID
4913
7587
  },
4914
7588
  url: {
4915
7589
  pattern: VALIDATION_PATTERNS.URL,
4916
- message: VALIDATION_MESSAGES.URL_INVALID
7590
+ message: VALIDATION_MESSAGES2.URL_INVALID
4917
7591
  }
4918
7592
  };
4919
7593