@exyconn/common 2.0.0 → 2.3.2

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.
Files changed (124) hide show
  1. package/README.md +864 -261
  2. package/dist/{index-BLltj-zN.d.ts → client/hooks/index.d.mts} +1 -195
  3. package/dist/{index-CIUdLBjA.d.mts → client/hooks/index.d.ts} +1 -195
  4. package/dist/client/hooks/index.js +2276 -0
  5. package/dist/client/hooks/index.js.map +1 -0
  6. package/dist/client/hooks/index.mjs +2217 -0
  7. package/dist/client/hooks/index.mjs.map +1 -0
  8. package/dist/client/index.d.mts +4 -1
  9. package/dist/client/index.d.ts +4 -1
  10. package/dist/client/index.js +2693 -19
  11. package/dist/client/index.js.map +1 -1
  12. package/dist/client/index.mjs +2634 -21
  13. package/dist/client/index.mjs.map +1 -1
  14. package/dist/client/web/index.d.mts +1461 -0
  15. package/dist/client/web/index.d.ts +1461 -0
  16. package/dist/client/web/index.js +2681 -0
  17. package/dist/client/web/index.js.map +1 -0
  18. package/dist/client/web/index.mjs +2618 -0
  19. package/dist/client/web/index.mjs.map +1 -0
  20. package/dist/data/brand-identity.d.mts +149 -0
  21. package/dist/data/brand-identity.d.ts +149 -0
  22. package/dist/data/brand-identity.js +235 -0
  23. package/dist/data/brand-identity.js.map +1 -0
  24. package/dist/data/brand-identity.mjs +220 -0
  25. package/dist/data/brand-identity.mjs.map +1 -0
  26. package/dist/data/countries.d.mts +61 -0
  27. package/dist/data/countries.d.ts +61 -0
  28. package/dist/data/countries.js +987 -0
  29. package/dist/data/countries.js.map +1 -0
  30. package/dist/data/countries.mjs +971 -0
  31. package/dist/data/countries.mjs.map +1 -0
  32. package/dist/data/currencies.d.mts +19 -0
  33. package/dist/data/currencies.d.ts +19 -0
  34. package/dist/data/currencies.js +162 -0
  35. package/dist/data/currencies.js.map +1 -0
  36. package/dist/data/currencies.mjs +153 -0
  37. package/dist/data/currencies.mjs.map +1 -0
  38. package/dist/data/index.d.mts +7 -0
  39. package/dist/data/index.d.ts +7 -0
  40. package/dist/data/index.js +2087 -0
  41. package/dist/data/index.js.map +1 -0
  42. package/dist/data/index.mjs +1948 -0
  43. package/dist/data/index.mjs.map +1 -0
  44. package/dist/data/phone-codes.d.mts +15 -0
  45. package/dist/data/phone-codes.d.ts +15 -0
  46. package/dist/data/phone-codes.js +219 -0
  47. package/dist/data/phone-codes.js.map +1 -0
  48. package/dist/data/phone-codes.mjs +211 -0
  49. package/dist/data/phone-codes.mjs.map +1 -0
  50. package/dist/data/regex.d.mts +287 -0
  51. package/dist/data/regex.d.ts +287 -0
  52. package/dist/data/regex.js +306 -0
  53. package/dist/data/regex.js.map +1 -0
  54. package/dist/data/regex.mjs +208 -0
  55. package/dist/data/regex.mjs.map +1 -0
  56. package/dist/data/timezones.d.mts +16 -0
  57. package/dist/data/timezones.d.ts +16 -0
  58. package/dist/data/timezones.js +98 -0
  59. package/dist/data/timezones.js.map +1 -0
  60. package/dist/data/timezones.mjs +89 -0
  61. package/dist/data/timezones.mjs.map +1 -0
  62. package/dist/index-01hoqibP.d.ts +119 -0
  63. package/dist/index-D3yCCjBZ.d.mts +119 -0
  64. package/dist/index-D9a9oxQy.d.ts +305 -0
  65. package/dist/index-DKn4raO7.d.ts +222 -0
  66. package/dist/index-DuxL84IW.d.mts +305 -0
  67. package/dist/index-NS8dS0p9.d.mts +222 -0
  68. package/dist/index-Nqm5_lwT.d.ts +188 -0
  69. package/dist/index-jBi3V6e5.d.mts +188 -0
  70. package/dist/index.d.mts +21 -729
  71. package/dist/index.d.ts +21 -729
  72. package/dist/index.js +3470 -97
  73. package/dist/index.js.map +1 -1
  74. package/dist/index.mjs +3457 -104
  75. package/dist/index.mjs.map +1 -1
  76. package/dist/server/configs/index.d.mts +602 -0
  77. package/dist/server/configs/index.d.ts +602 -0
  78. package/dist/server/configs/index.js +707 -0
  79. package/dist/server/configs/index.js.map +1 -0
  80. package/dist/server/configs/index.mjs +665 -0
  81. package/dist/server/configs/index.mjs.map +1 -0
  82. package/dist/server/index.d.mts +3 -0
  83. package/dist/server/index.d.ts +3 -0
  84. package/dist/server/index.js +699 -0
  85. package/dist/server/index.js.map +1 -1
  86. package/dist/server/index.mjs +662 -1
  87. package/dist/server/index.mjs.map +1 -1
  88. package/dist/shared/config/index.d.mts +40 -0
  89. package/dist/shared/config/index.d.ts +40 -0
  90. package/dist/shared/config/index.js +58 -0
  91. package/dist/shared/config/index.js.map +1 -0
  92. package/dist/shared/config/index.mjs +51 -0
  93. package/dist/shared/config/index.mjs.map +1 -0
  94. package/dist/shared/constants/index.d.mts +593 -0
  95. package/dist/shared/constants/index.d.ts +593 -0
  96. package/dist/shared/constants/index.js +391 -0
  97. package/dist/shared/constants/index.js.map +1 -0
  98. package/dist/shared/constants/index.mjs +360 -0
  99. package/dist/shared/constants/index.mjs.map +1 -0
  100. package/dist/shared/index.d.mts +5 -1
  101. package/dist/shared/index.d.ts +5 -1
  102. package/dist/shared/types/index.d.mts +140 -0
  103. package/dist/shared/types/index.d.ts +140 -0
  104. package/dist/shared/types/index.js +4 -0
  105. package/dist/shared/types/index.js.map +1 -0
  106. package/dist/shared/types/index.mjs +3 -0
  107. package/dist/shared/types/index.mjs.map +1 -0
  108. package/dist/shared/utils/index.d.mts +255 -0
  109. package/dist/shared/utils/index.d.ts +255 -0
  110. package/dist/shared/utils/index.js +623 -0
  111. package/dist/shared/utils/index.js.map +1 -0
  112. package/dist/shared/utils/index.mjs +324 -0
  113. package/dist/shared/utils/index.mjs.map +1 -0
  114. package/dist/shared/validation/index.d.mts +258 -0
  115. package/dist/shared/validation/index.d.ts +258 -0
  116. package/dist/shared/validation/index.js +185 -0
  117. package/dist/shared/validation/index.js.map +1 -0
  118. package/dist/shared/validation/index.mjs +172 -0
  119. package/dist/shared/validation/index.mjs.map +1 -0
  120. package/package.json +151 -56
  121. package/dist/index-DEzgM15j.d.ts +0 -67
  122. package/dist/index-DNFVgQx8.d.ts +0 -1375
  123. package/dist/index-DbV04Dx8.d.mts +0 -67
  124. package/dist/index-DfqEP6Oe.d.mts +0 -1375
package/dist/index.js CHANGED
@@ -6,19 +6,43 @@ var path = require('path');
6
6
  var mongoose = require('mongoose');
7
7
  var jwt = require('jsonwebtoken');
8
8
  var fs = require('fs');
9
+ var rateLimit = require('express-rate-limit');
9
10
  var axios = require('axios');
10
11
  var react = require('react');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+ var Yup = require('yup');
14
+ var formik = require('formik');
11
15
  var dateFns = require('date-fns');
12
16
  var dateFnsTz = require('date-fns-tz');
13
17
 
14
18
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
19
 
20
+ function _interopNamespace(e) {
21
+ if (e && e.__esModule) return e;
22
+ var n = Object.create(null);
23
+ if (e) {
24
+ Object.keys(e).forEach(function (k) {
25
+ if (k !== 'default') {
26
+ var d = Object.getOwnPropertyDescriptor(e, k);
27
+ Object.defineProperty(n, k, d.get ? d : {
28
+ enumerable: true,
29
+ get: function () { return e[k]; }
30
+ });
31
+ }
32
+ });
33
+ }
34
+ n.default = e;
35
+ return Object.freeze(n);
36
+ }
37
+
16
38
  var winston__default = /*#__PURE__*/_interopDefault(winston);
17
39
  var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
18
40
  var path__default = /*#__PURE__*/_interopDefault(path);
19
41
  var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
20
42
  var jwt__default = /*#__PURE__*/_interopDefault(jwt);
43
+ var rateLimit__default = /*#__PURE__*/_interopDefault(rateLimit);
21
44
  var axios__default = /*#__PURE__*/_interopDefault(axios);
45
+ var Yup__namespace = /*#__PURE__*/_interopNamespace(Yup);
22
46
 
23
47
  var __defProp = Object.defineProperty;
24
48
  var __export = (target, all) => {
@@ -29,20 +53,50 @@ var __export = (target, all) => {
29
53
  // src/server/index.ts
30
54
  var server_exports = {};
31
55
  __export(server_exports, {
56
+ ConfigBuilder: () => ConfigBuilder,
57
+ DEFAULT_AUTH_CONFIG: () => DEFAULT_AUTH_CONFIG,
58
+ DEFAULT_CORS_CONFIG: () => DEFAULT_CORS_CONFIG,
59
+ DEFAULT_CORS_ORIGINS: () => DEFAULT_CORS_ORIGINS,
60
+ DEFAULT_DATABASE_CONFIG: () => DEFAULT_DATABASE_CONFIG,
61
+ DEFAULT_LOGGING_CONFIG: () => DEFAULT_LOGGING_CONFIG,
62
+ DEFAULT_RATE_LIMIT_CONFIG: () => DEFAULT_RATE_LIMIT_CONFIG,
63
+ DEFAULT_RATE_LIMIT_TIERS: () => DEFAULT_RATE_LIMIT_TIERS,
64
+ DEFAULT_SERVER_CONFIG: () => DEFAULT_SERVER_CONFIG,
65
+ EXYCONN_CORS_CONFIG: () => EXYCONN_CORS_CONFIG,
66
+ PERMISSIVE_CORS_CONFIG: () => PERMISSIVE_CORS_CONFIG,
67
+ RATE_LIMIT_CONFIG: () => RATE_LIMIT_CONFIG,
68
+ RateLimiterBuilder: () => RateLimiterBuilder,
69
+ STRICT_CORS_CONFIG: () => STRICT_CORS_CONFIG,
32
70
  StatusCode: () => StatusCode,
33
71
  StatusMessage: () => StatusMessage,
34
72
  authenticateApiKey: () => authenticateApiKey,
35
73
  authenticateJWT: () => authenticateJWT,
36
74
  badRequestResponse: () => badRequestResponse,
75
+ buildConfig: () => buildConfig,
37
76
  buildFilter: () => buildFilter,
38
77
  buildPagination: () => buildPagination,
39
78
  buildPaginationMeta: () => buildPaginationMeta,
40
79
  checkPackageServer: () => checkPackageServer,
41
80
  conflictResponse: () => conflictResponse,
42
81
  connectDB: () => connectDB,
82
+ corsOptions: () => corsOptions,
83
+ createApiKeyGenerator: () => createApiKeyGenerator,
84
+ createApiRateLimiter: () => createApiRateLimiter,
85
+ createBrandCorsOptions: () => createBrandCorsOptions,
86
+ createConfig: () => createConfig,
87
+ createCorsOptions: () => createCorsOptions,
88
+ createDdosRateLimiter: () => createDdosRateLimiter,
43
89
  createLogger: () => createLogger,
44
90
  createMorganStream: () => createMorganStream,
91
+ createMultiBrandCorsOptions: () => createMultiBrandCorsOptions,
92
+ createPrefixedKeyGenerator: () => createPrefixedKeyGenerator,
93
+ createRateLimiter: () => createRateLimiter,
94
+ createStandardRateLimiter: () => createStandardRateLimiter,
95
+ createStrictRateLimiter: () => createStrictRateLimiter,
96
+ createUserKeyGenerator: () => createUserKeyGenerator,
45
97
  createdResponse: () => createdResponse,
98
+ ddosProtectionLimiter: () => ddosProtectionLimiter,
99
+ defaultKeyGenerator: () => defaultKeyGenerator,
46
100
  disconnectDB: () => disconnectDB,
47
101
  errorResponse: () => errorResponse,
48
102
  extractColumns: () => extractColumns,
@@ -51,6 +105,10 @@ __export(server_exports, {
51
105
  formatPackageCheckResult: () => formatPackageCheckResult,
52
106
  generateNcuCommand: () => generateNcuCommand,
53
107
  getConnectionStatus: () => getConnectionStatus,
108
+ getDatabaseOptions: () => getDatabaseOptions,
109
+ isDevelopment: () => isDevelopment,
110
+ isProduction: () => isProduction,
111
+ isTest: () => isTest,
54
112
  logger: () => logger,
55
113
  noContentResponse: () => noContentResponse,
56
114
  notFoundResponse: () => notFoundResponse,
@@ -60,13 +118,16 @@ __export(server_exports, {
60
118
  pickFields: () => pickFields,
61
119
  printPackageCheckSummary: () => printPackageCheckSummary,
62
120
  rateLimitResponse: () => rateLimitResponse,
121
+ rateLimiter: () => rateLimiter,
63
122
  requireOrganization: () => requireOrganization,
64
123
  sanitizeDocument: () => sanitizeDocument,
65
124
  sanitizeUser: () => sanitizeUser,
66
125
  simpleLogger: () => simpleLogger,
126
+ standardRateLimiter: () => standardRateLimiter,
67
127
  statusCode: () => statusCode,
68
128
  statusMessage: () => statusMessage,
69
129
  stream: () => stream,
130
+ strictRateLimiter: () => strictRateLimiter,
70
131
  successResponse: () => successResponse,
71
132
  successResponseArr: () => successResponseArr,
72
133
  unauthorizedResponse: () => unauthorizedResponse,
@@ -778,19 +839,689 @@ var packageCheckServer = {
778
839
  print: printPackageCheckSummary
779
840
  };
780
841
 
842
+ // src/server/configs/cors.config.ts
843
+ var DEFAULT_CORS_CONFIG = {
844
+ productionOrigins: [],
845
+ developmentOrigins: [
846
+ "http://localhost:3000",
847
+ "http://localhost:4000",
848
+ "http://localhost:5000",
849
+ "http://localhost:5173",
850
+ "http://localhost:8080",
851
+ "http://127.0.0.1:3000",
852
+ "http://127.0.0.1:4000",
853
+ "http://127.0.0.1:5000",
854
+ "http://127.0.0.1:5173",
855
+ "http://127.0.0.1:8080"
856
+ ],
857
+ allowedSubdomains: [],
858
+ originPatterns: [],
859
+ allowNoOrigin: true,
860
+ allowAllInDev: true,
861
+ credentials: true,
862
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"],
863
+ allowedHeaders: [
864
+ "Content-Type",
865
+ "Authorization",
866
+ "X-Requested-With",
867
+ "Accept",
868
+ "Origin",
869
+ "X-API-Key",
870
+ "X-Organization-Id",
871
+ "X-Request-Id"
872
+ ],
873
+ exposedHeaders: [
874
+ "Content-Range",
875
+ "X-Content-Range",
876
+ "X-Total-Count",
877
+ "X-Request-Id"
878
+ ],
879
+ maxAge: 86400
880
+ // 24 hours
881
+ };
882
+ var createCorsOptions = (config = {}) => {
883
+ const finalConfig = { ...DEFAULT_CORS_CONFIG, ...config };
884
+ const {
885
+ productionOrigins,
886
+ developmentOrigins,
887
+ allowedSubdomains,
888
+ originPatterns,
889
+ allowNoOrigin,
890
+ allowAllInDev,
891
+ customValidator,
892
+ credentials,
893
+ methods,
894
+ allowedHeaders,
895
+ exposedHeaders,
896
+ maxAge
897
+ } = finalConfig;
898
+ const allOrigins = /* @__PURE__ */ new Set([...productionOrigins, ...developmentOrigins]);
899
+ const originHandler = (origin, callback) => {
900
+ if (!origin) {
901
+ callback(null, allowNoOrigin);
902
+ return;
903
+ }
904
+ if (allOrigins.has(origin)) {
905
+ callback(null, true);
906
+ return;
907
+ }
908
+ if (allowedSubdomains.some((subdomain) => origin.endsWith(subdomain))) {
909
+ callback(null, true);
910
+ return;
911
+ }
912
+ if (originPatterns.some((pattern) => pattern.test(origin))) {
913
+ callback(null, true);
914
+ return;
915
+ }
916
+ if (customValidator && customValidator(origin)) {
917
+ callback(null, true);
918
+ return;
919
+ }
920
+ if (process.env.NODE_ENV !== "production" && allowAllInDev) {
921
+ callback(null, true);
922
+ return;
923
+ }
924
+ if (process.env.NODE_ENV === "production") {
925
+ callback(new Error(`Origin ${origin} not allowed by CORS`));
926
+ return;
927
+ }
928
+ callback(null, true);
929
+ };
930
+ return {
931
+ origin: originHandler,
932
+ credentials,
933
+ methods,
934
+ allowedHeaders,
935
+ exposedHeaders,
936
+ maxAge
937
+ };
938
+ };
939
+ var createBrandCorsOptions = (brandDomain, additionalConfig = {}) => {
940
+ const productionOrigins = [
941
+ `https://${brandDomain}`,
942
+ `https://www.${brandDomain}`
943
+ ];
944
+ const allowedSubdomains = [`.${brandDomain}`];
945
+ return createCorsOptions({
946
+ productionOrigins,
947
+ allowedSubdomains,
948
+ ...additionalConfig
949
+ });
950
+ };
951
+ var createMultiBrandCorsOptions = (domains, additionalConfig = {}) => {
952
+ const productionOrigins = domains.flatMap((domain) => [
953
+ `https://${domain}`,
954
+ `https://www.${domain}`
955
+ ]);
956
+ const allowedSubdomains = domains.map((domain) => `.${domain}`);
957
+ return createCorsOptions({
958
+ productionOrigins,
959
+ allowedSubdomains,
960
+ ...additionalConfig
961
+ });
962
+ };
963
+ var EXYCONN_CORS_CONFIG = {
964
+ productionOrigins: [
965
+ "https://exyconn.com",
966
+ "https://www.exyconn.com",
967
+ "https://botify.life",
968
+ "https://www.botify.life",
969
+ "https://partywings.fun",
970
+ "https://www.partywings.fun",
971
+ "https://sibera.work",
972
+ "https://www.sibera.work",
973
+ "https://spentiva.com",
974
+ "https://www.spentiva.com"
975
+ ],
976
+ allowedSubdomains: [
977
+ ".exyconn.com",
978
+ ".botify.life",
979
+ ".partywings.fun",
980
+ ".sibera.work",
981
+ ".spentiva.com"
982
+ ],
983
+ developmentOrigins: [
984
+ "http://localhost:3000",
985
+ "http://localhost:4000",
986
+ "http://localhost:4001",
987
+ "http://localhost:4002",
988
+ "http://localhost:4003",
989
+ "http://localhost:4004",
990
+ "http://localhost:4005",
991
+ "http://localhost:5173",
992
+ "http://127.0.0.1:3000",
993
+ "http://127.0.0.1:4000",
994
+ "http://127.0.0.1:5173"
995
+ ]
996
+ };
997
+ var STRICT_CORS_CONFIG = {
998
+ allowNoOrigin: false,
999
+ allowAllInDev: false,
1000
+ methods: ["GET", "POST", "PUT", "DELETE"]
1001
+ };
1002
+ var PERMISSIVE_CORS_CONFIG = {
1003
+ allowNoOrigin: true,
1004
+ allowAllInDev: true,
1005
+ originPatterns: [/localhost/, /127\.0\.0\.1/]
1006
+ };
1007
+ var corsOptions = createCorsOptions(EXYCONN_CORS_CONFIG);
1008
+ var DEFAULT_RATE_LIMIT_TIERS = {
1009
+ STANDARD: {
1010
+ windowMs: 15 * 60 * 1e3,
1011
+ // 15 minutes
1012
+ maxRequests: 100,
1013
+ message: "Too many requests, please try again later.",
1014
+ skipSuccessfulRequests: false,
1015
+ skipFailedRequests: false
1016
+ },
1017
+ STRICT: {
1018
+ windowMs: 15 * 60 * 1e3,
1019
+ // 15 minutes
1020
+ maxRequests: 20,
1021
+ message: "Too many requests, please try again later.",
1022
+ skipSuccessfulRequests: false,
1023
+ skipFailedRequests: false
1024
+ },
1025
+ DDOS: {
1026
+ windowMs: 60 * 1e3,
1027
+ // 1 minute
1028
+ maxRequests: 60,
1029
+ message: "Rate limit exceeded. Please slow down.",
1030
+ skipSuccessfulRequests: false,
1031
+ skipFailedRequests: false
1032
+ },
1033
+ // Additional presets
1034
+ VERY_STRICT: {
1035
+ windowMs: 60 * 60 * 1e3,
1036
+ // 1 hour
1037
+ maxRequests: 5,
1038
+ message: "Too many attempts. Please try again in an hour.",
1039
+ skipSuccessfulRequests: false,
1040
+ skipFailedRequests: false
1041
+ },
1042
+ RELAXED: {
1043
+ windowMs: 15 * 60 * 1e3,
1044
+ // 15 minutes
1045
+ maxRequests: 500,
1046
+ message: "Rate limit exceeded.",
1047
+ skipSuccessfulRequests: false,
1048
+ skipFailedRequests: false
1049
+ },
1050
+ API: {
1051
+ windowMs: 60 * 1e3,
1052
+ // 1 minute
1053
+ maxRequests: 30,
1054
+ message: "API rate limit exceeded.",
1055
+ skipSuccessfulRequests: false,
1056
+ skipFailedRequests: false
1057
+ }
1058
+ };
1059
+ var defaultKeyGenerator = (req) => {
1060
+ const forwarded = req.headers["x-forwarded-for"];
1061
+ const ip = forwarded ? Array.isArray(forwarded) ? forwarded[0] : forwarded.split(",")[0].trim() : req.ip || req.socket.remoteAddress || "unknown";
1062
+ return ip;
1063
+ };
1064
+ var createPrefixedKeyGenerator = (prefix) => (req) => {
1065
+ return `${prefix}:${defaultKeyGenerator(req)}`;
1066
+ };
1067
+ var createUserKeyGenerator = (getUserId) => (req) => {
1068
+ const userId = getUserId(req);
1069
+ return userId || defaultKeyGenerator(req);
1070
+ };
1071
+ var createApiKeyGenerator = (headerName = "x-api-key") => (req) => {
1072
+ const apiKey = req.headers[headerName.toLowerCase()];
1073
+ return apiKey || defaultKeyGenerator(req);
1074
+ };
1075
+ var createRateLimitResponse = (message, retryAfter) => ({
1076
+ status: "error",
1077
+ statusCode: 429,
1078
+ message,
1079
+ ...retryAfter
1080
+ });
1081
+ var createRateLimiter = (tierConfig, options = {}) => {
1082
+ const {
1083
+ standardHeaders = true,
1084
+ legacyHeaders = false,
1085
+ keyGenerator = defaultKeyGenerator,
1086
+ skip,
1087
+ handler
1088
+ } = options;
1089
+ return rateLimit__default.default({
1090
+ windowMs: tierConfig.windowMs,
1091
+ max: tierConfig.maxRequests,
1092
+ message: createRateLimitResponse(tierConfig.message),
1093
+ standardHeaders,
1094
+ legacyHeaders,
1095
+ keyGenerator,
1096
+ skip,
1097
+ handler,
1098
+ skipSuccessfulRequests: tierConfig.skipSuccessfulRequests,
1099
+ skipFailedRequests: tierConfig.skipFailedRequests
1100
+ });
1101
+ };
1102
+ var createStandardRateLimiter = (config = {}, options = {}) => {
1103
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STANDARD, ...config };
1104
+ return createRateLimiter(tierConfig, options);
1105
+ };
1106
+ var createStrictRateLimiter = (config = {}, options = {}) => {
1107
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STRICT, ...config };
1108
+ return createRateLimiter(tierConfig, options);
1109
+ };
1110
+ var createDdosRateLimiter = (config = {}, options = {}) => {
1111
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.DDOS, ...config };
1112
+ return createRateLimiter(tierConfig, options);
1113
+ };
1114
+ var createApiRateLimiter = (config = {}, options = {}) => {
1115
+ const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.API, ...config };
1116
+ return createRateLimiter(tierConfig, {
1117
+ keyGenerator: createApiKeyGenerator(),
1118
+ ...options
1119
+ });
1120
+ };
1121
+ var RateLimiterBuilder = class {
1122
+ constructor(preset = "STANDARD") {
1123
+ const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];
1124
+ this.config = {
1125
+ windowMs: presetConfig.windowMs,
1126
+ maxRequests: presetConfig.maxRequests,
1127
+ message: presetConfig.message,
1128
+ skipSuccessfulRequests: presetConfig.skipSuccessfulRequests ?? false,
1129
+ skipFailedRequests: presetConfig.skipFailedRequests ?? false
1130
+ };
1131
+ this.options = {};
1132
+ }
1133
+ /**
1134
+ * Set window duration
1135
+ */
1136
+ windowMs(ms) {
1137
+ this.config.windowMs = ms;
1138
+ return this;
1139
+ }
1140
+ /**
1141
+ * Set window duration in minutes
1142
+ */
1143
+ windowMinutes(minutes) {
1144
+ this.config.windowMs = minutes * 60 * 1e3;
1145
+ return this;
1146
+ }
1147
+ /**
1148
+ * Set window duration in hours
1149
+ */
1150
+ windowHours(hours) {
1151
+ this.config.windowMs = hours * 60 * 60 * 1e3;
1152
+ return this;
1153
+ }
1154
+ /**
1155
+ * Set maximum requests
1156
+ */
1157
+ max(requests) {
1158
+ this.config.maxRequests = requests;
1159
+ return this;
1160
+ }
1161
+ /**
1162
+ * Set error message
1163
+ */
1164
+ message(msg) {
1165
+ this.config.message = msg;
1166
+ return this;
1167
+ }
1168
+ /**
1169
+ * Skip successful requests
1170
+ */
1171
+ skipSuccessful(skip = true) {
1172
+ this.config.skipSuccessfulRequests = skip;
1173
+ return this;
1174
+ }
1175
+ /**
1176
+ * Skip failed requests
1177
+ */
1178
+ skipFailed(skip = true) {
1179
+ this.config.skipFailedRequests = skip;
1180
+ return this;
1181
+ }
1182
+ /**
1183
+ * Set key generator
1184
+ */
1185
+ keyBy(generator) {
1186
+ this.options.keyGenerator = generator;
1187
+ return this;
1188
+ }
1189
+ /**
1190
+ * Key by IP (default)
1191
+ */
1192
+ keyByIp() {
1193
+ this.options.keyGenerator = defaultKeyGenerator;
1194
+ return this;
1195
+ }
1196
+ /**
1197
+ * Key by API key
1198
+ */
1199
+ keyByApiKey(headerName) {
1200
+ this.options.keyGenerator = createApiKeyGenerator(headerName);
1201
+ return this;
1202
+ }
1203
+ /**
1204
+ * Skip certain requests
1205
+ */
1206
+ skipWhen(predicate) {
1207
+ this.options.skip = predicate;
1208
+ return this;
1209
+ }
1210
+ /**
1211
+ * Build the rate limiter
1212
+ */
1213
+ build() {
1214
+ return createRateLimiter(this.config, this.options);
1215
+ }
1216
+ };
1217
+ var rateLimiter = (preset) => {
1218
+ return new RateLimiterBuilder(preset);
1219
+ };
1220
+ var RATE_LIMIT_CONFIG = {
1221
+ STANDARD: DEFAULT_RATE_LIMIT_TIERS.STANDARD,
1222
+ STRICT: DEFAULT_RATE_LIMIT_TIERS.STRICT,
1223
+ DDOS: DEFAULT_RATE_LIMIT_TIERS.DDOS
1224
+ };
1225
+ var standardRateLimiter = createStandardRateLimiter();
1226
+ var strictRateLimiter = createStrictRateLimiter();
1227
+ var ddosProtectionLimiter = createDdosRateLimiter();
1228
+
1229
+ // src/server/configs/server.config.ts
1230
+ var DEFAULT_SERVER_CONFIG = {
1231
+ name: "app-server",
1232
+ version: "1.0.0",
1233
+ environment: process.env.NODE_ENV || "development",
1234
+ port: parseInt(process.env.PORT || "3000", 10),
1235
+ host: process.env.HOST || "0.0.0.0",
1236
+ basePath: "/api",
1237
+ debug: process.env.DEBUG === "true",
1238
+ trustProxy: true
1239
+ };
1240
+ var DEFAULT_DATABASE_CONFIG = {
1241
+ uri: process.env.DATABASE_URL || process.env.MONGODB_URI || "",
1242
+ name: process.env.DATABASE_NAME || "app_db",
1243
+ maxPoolSize: process.env.NODE_ENV === "production" ? 50 : 10,
1244
+ minPoolSize: process.env.NODE_ENV === "production" ? 10 : 5,
1245
+ socketTimeoutMS: 45e3,
1246
+ serverSelectionTimeoutMS: 1e4,
1247
+ maxIdleTimeMS: 1e4,
1248
+ retryWrites: true,
1249
+ retryReads: true,
1250
+ writeConcern: "majority"
1251
+ };
1252
+ var DEFAULT_AUTH_CONFIG = {
1253
+ jwtSecret: process.env.JWT_SECRET || "",
1254
+ jwtExpiresIn: process.env.JWT_EXPIRES_IN || "7d",
1255
+ refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || "30d",
1256
+ enableRefreshTokens: true,
1257
+ apiKeyHeader: "x-api-key",
1258
+ orgHeader: "x-organization-id"
1259
+ };
1260
+ var DEFAULT_LOGGING_CONFIG = {
1261
+ level: process.env.LOG_LEVEL || "info",
1262
+ logsDir: process.env.LOGS_DIR || "logs",
1263
+ maxSize: "20m",
1264
+ maxFiles: "14d",
1265
+ errorMaxFiles: "30d",
1266
+ console: true,
1267
+ file: process.env.NODE_ENV === "production",
1268
+ json: process.env.NODE_ENV === "production"
1269
+ };
1270
+ var DEFAULT_CORS_ORIGINS = {
1271
+ production: [],
1272
+ development: [
1273
+ "http://localhost:3000",
1274
+ "http://localhost:4000",
1275
+ "http://localhost:5173",
1276
+ "http://127.0.0.1:3000",
1277
+ "http://127.0.0.1:4000",
1278
+ "http://127.0.0.1:5173"
1279
+ ],
1280
+ patterns: []
1281
+ };
1282
+ var DEFAULT_RATE_LIMIT_CONFIG = {
1283
+ enabled: true,
1284
+ standard: {
1285
+ windowMs: 15 * 60 * 1e3,
1286
+ // 15 minutes
1287
+ maxRequests: 100,
1288
+ message: "Too many requests, please try again later."
1289
+ },
1290
+ strict: {
1291
+ windowMs: 15 * 60 * 1e3,
1292
+ // 15 minutes
1293
+ maxRequests: 20,
1294
+ message: "Too many requests, please try again later."
1295
+ },
1296
+ ddos: {
1297
+ windowMs: 60 * 1e3,
1298
+ // 1 minute
1299
+ maxRequests: 60,
1300
+ message: "Rate limit exceeded. Please slow down.",
1301
+ skipSuccessfulRequests: false
1302
+ }
1303
+ };
1304
+ function deepMerge(target, source) {
1305
+ const result = { ...target };
1306
+ for (const key in source) {
1307
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1308
+ const sourceValue = source[key];
1309
+ const targetValue = target[key];
1310
+ if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
1311
+ result[key] = deepMerge(
1312
+ targetValue,
1313
+ sourceValue
1314
+ );
1315
+ } else if (sourceValue !== void 0) {
1316
+ result[key] = sourceValue;
1317
+ }
1318
+ }
1319
+ }
1320
+ return result;
1321
+ }
1322
+ var ConfigBuilder = class {
1323
+ constructor() {
1324
+ this.config = {
1325
+ server: { ...DEFAULT_SERVER_CONFIG },
1326
+ database: { ...DEFAULT_DATABASE_CONFIG },
1327
+ auth: { ...DEFAULT_AUTH_CONFIG },
1328
+ logging: { ...DEFAULT_LOGGING_CONFIG },
1329
+ cors: { ...DEFAULT_CORS_ORIGINS },
1330
+ rateLimit: { ...DEFAULT_RATE_LIMIT_CONFIG }
1331
+ };
1332
+ }
1333
+ /**
1334
+ * Set server configuration
1335
+ */
1336
+ setServer(config) {
1337
+ this.config.server = deepMerge(this.config.server, config);
1338
+ return this;
1339
+ }
1340
+ /**
1341
+ * Set database configuration
1342
+ */
1343
+ setDatabase(config) {
1344
+ this.config.database = deepMerge(this.config.database, config);
1345
+ return this;
1346
+ }
1347
+ /**
1348
+ * Set auth configuration
1349
+ */
1350
+ setAuth(config) {
1351
+ this.config.auth = deepMerge(this.config.auth, config);
1352
+ return this;
1353
+ }
1354
+ /**
1355
+ * Set logging configuration
1356
+ */
1357
+ setLogging(config) {
1358
+ this.config.logging = deepMerge(this.config.logging, config);
1359
+ return this;
1360
+ }
1361
+ /**
1362
+ * Set CORS origins
1363
+ */
1364
+ setCorsOrigins(config) {
1365
+ this.config.cors = deepMerge(this.config.cors, config);
1366
+ return this;
1367
+ }
1368
+ /**
1369
+ * Add CORS production origin
1370
+ */
1371
+ addProductionOrigin(origin) {
1372
+ if (!this.config.cors.production.includes(origin)) {
1373
+ this.config.cors.production.push(origin);
1374
+ }
1375
+ return this;
1376
+ }
1377
+ /**
1378
+ * Add CORS development origin
1379
+ */
1380
+ addDevelopmentOrigin(origin) {
1381
+ if (!this.config.cors.development.includes(origin)) {
1382
+ this.config.cors.development.push(origin);
1383
+ }
1384
+ return this;
1385
+ }
1386
+ /**
1387
+ * Add CORS pattern
1388
+ */
1389
+ addCorsPattern(pattern) {
1390
+ if (!this.config.cors.patterns.includes(pattern)) {
1391
+ this.config.cors.patterns.push(pattern);
1392
+ }
1393
+ return this;
1394
+ }
1395
+ /**
1396
+ * Set rate limit configuration
1397
+ */
1398
+ setRateLimit(config) {
1399
+ this.config.rateLimit = deepMerge(this.config.rateLimit, config);
1400
+ return this;
1401
+ }
1402
+ /**
1403
+ * Add custom rate limit tier
1404
+ */
1405
+ addRateLimitTier(name, tier) {
1406
+ if (!this.config.rateLimit.custom) {
1407
+ this.config.rateLimit.custom = {};
1408
+ }
1409
+ this.config.rateLimit.custom[name] = tier;
1410
+ return this;
1411
+ }
1412
+ /**
1413
+ * Set custom configuration
1414
+ */
1415
+ setCustom(key, value) {
1416
+ if (!this.config.custom) {
1417
+ this.config.custom = {};
1418
+ }
1419
+ this.config.custom[key] = value;
1420
+ return this;
1421
+ }
1422
+ /**
1423
+ * Load configuration from environment variables
1424
+ */
1425
+ loadFromEnv() {
1426
+ if (process.env.SERVER_NAME) this.config.server.name = process.env.SERVER_NAME;
1427
+ if (process.env.SERVER_VERSION) this.config.server.version = process.env.SERVER_VERSION;
1428
+ if (process.env.PORT) this.config.server.port = parseInt(process.env.PORT, 10);
1429
+ if (process.env.HOST) this.config.server.host = process.env.HOST;
1430
+ if (process.env.BASE_PATH) this.config.server.basePath = process.env.BASE_PATH;
1431
+ if (process.env.DATABASE_URL) this.config.database.uri = process.env.DATABASE_URL;
1432
+ if (process.env.MONGODB_URI) this.config.database.uri = process.env.MONGODB_URI;
1433
+ if (process.env.DATABASE_NAME) this.config.database.name = process.env.DATABASE_NAME;
1434
+ if (process.env.JWT_SECRET) this.config.auth.jwtSecret = process.env.JWT_SECRET;
1435
+ if (process.env.JWT_EXPIRES_IN) this.config.auth.jwtExpiresIn = process.env.JWT_EXPIRES_IN;
1436
+ if (process.env.LOG_LEVEL) this.config.logging.level = process.env.LOG_LEVEL;
1437
+ if (process.env.LOGS_DIR) this.config.logging.logsDir = process.env.LOGS_DIR;
1438
+ if (process.env.CORS_ORIGINS) {
1439
+ const origins = process.env.CORS_ORIGINS.split(",").map((o) => o.trim());
1440
+ this.config.cors.production.push(...origins);
1441
+ }
1442
+ return this;
1443
+ }
1444
+ /**
1445
+ * Validate configuration
1446
+ */
1447
+ validate() {
1448
+ const errors = [];
1449
+ if (!this.config.server.name) errors.push("Server name is required");
1450
+ if (this.config.server.port < 1 || this.config.server.port > 65535) {
1451
+ errors.push("Server port must be between 1 and 65535");
1452
+ }
1453
+ if (this.config.server.environment === "production") {
1454
+ if (!this.config.auth.jwtSecret || this.config.auth.jwtSecret.length < 32) {
1455
+ errors.push("JWT secret must be at least 32 characters in production");
1456
+ }
1457
+ }
1458
+ return { valid: errors.length === 0, errors };
1459
+ }
1460
+ /**
1461
+ * Build the final configuration
1462
+ */
1463
+ build() {
1464
+ return { ...this.config };
1465
+ }
1466
+ };
1467
+ var createConfig = () => {
1468
+ return new ConfigBuilder();
1469
+ };
1470
+ var buildConfig = (partial = {}) => {
1471
+ const builder = createConfig().loadFromEnv();
1472
+ if (partial.server) builder.setServer(partial.server);
1473
+ if (partial.database) builder.setDatabase(partial.database);
1474
+ if (partial.auth) builder.setAuth(partial.auth);
1475
+ if (partial.logging) builder.setLogging(partial.logging);
1476
+ if (partial.cors) builder.setCorsOrigins(partial.cors);
1477
+ if (partial.rateLimit) builder.setRateLimit(partial.rateLimit);
1478
+ return builder.build();
1479
+ };
1480
+ var isProduction = (config) => {
1481
+ return (config?.environment || process.env.NODE_ENV) === "production";
1482
+ };
1483
+ var isDevelopment = (config) => {
1484
+ return (config?.environment || process.env.NODE_ENV) === "development";
1485
+ };
1486
+ var isTest = (config) => {
1487
+ return (config?.environment || process.env.NODE_ENV) === "test";
1488
+ };
1489
+ var getDatabaseOptions = (config) => {
1490
+ return {
1491
+ maxPoolSize: config.maxPoolSize,
1492
+ minPoolSize: config.minPoolSize,
1493
+ socketTimeoutMS: config.socketTimeoutMS,
1494
+ serverSelectionTimeoutMS: config.serverSelectionTimeoutMS,
1495
+ maxIdleTimeMS: config.maxIdleTimeMS,
1496
+ retryWrites: config.retryWrites,
1497
+ retryReads: config.retryReads,
1498
+ w: config.writeConcern
1499
+ };
1500
+ };
1501
+
781
1502
  // src/client/index.ts
782
1503
  var client_exports = {};
783
1504
  __export(client_exports, {
784
1505
  ApiUrlBuilder: () => ApiUrlBuilder,
785
1506
  ClientLogger: () => ClientLogger,
1507
+ ContactForm: () => ContactForm,
786
1508
  EventEmitter: () => EventEmitter,
1509
+ LoginForm: () => LoginForm,
1510
+ NewsletterForm: () => NewsletterForm,
1511
+ RegisterForm: () => RegisterForm,
1512
+ ThemeContext: () => ThemeContext,
1513
+ ThemeProvider: () => ThemeProvider,
1514
+ ThemeToggle: () => ThemeToggle,
1515
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
787
1516
  addDays: () => addDays,
1517
+ adjustColor: () => adjustColor,
788
1518
  appEvents: () => appEvents,
789
1519
  camelToKebab: () => camelToKebab,
790
1520
  capitalize: () => capitalize,
791
1521
  capitalizeWords: () => capitalizeWords,
792
1522
  checkPackage: () => checkPackage,
793
1523
  clientLogger: () => clientLogger,
1524
+ contactFormSchema: () => contactFormSchema,
794
1525
  copyToClipboard: () => copyToClipboard,
795
1526
  createApiEndpoints: () => createApiEndpoints,
796
1527
  createApiUrlBuilder: () => createApiUrlBuilder,
@@ -799,21 +1530,42 @@ __export(client_exports, {
799
1530
  createErrorResponse: () => createErrorResponse,
800
1531
  createEventEmitter: () => createEventEmitter,
801
1532
  createHttpClient: () => createHttpClient,
1533
+ createRegisterFormSchema: () => createRegisterFormSchema,
802
1534
  createSuccessResponse: () => createSuccessResponse,
1535
+ createTheme: () => createTheme,
1536
+ createThemeFromBrand: () => createThemeFromBrand,
1537
+ cssVar: () => cssVar,
1538
+ deepMerge: () => deepMerge2,
1539
+ defaultDarkTheme: () => defaultDarkTheme,
1540
+ defaultLightTheme: () => defaultLightTheme,
1541
+ dummyBannerData: () => dummyBannerData,
1542
+ dummyFaqItems: () => dummyFaqItems,
1543
+ dummyFeatures: () => dummyFeatures,
1544
+ dummyFooterData: () => dummyFooterData,
1545
+ dummyHeaderData: () => dummyHeaderData,
1546
+ dummyImage: () => dummyImage,
1547
+ dummyPricingPlans: () => dummyPricingPlans,
1548
+ dummyTestimonials: () => dummyTestimonials,
803
1549
  endOfDay: () => endOfDay,
1550
+ flattenToCssVars: () => flattenToCssVars,
804
1551
  formatDate: () => formatDate,
805
1552
  formatDateForInput: () => formatDateForInput,
806
1553
  formatDateTime: () => formatDateTime,
807
1554
  formatDateTimeForInput: () => formatDateTimeForInput,
808
1555
  formatPackageCheckResult: () => formatPackageCheckResult2,
809
1556
  formatRelativeTime: () => formatRelativeTime,
1557
+ generateCssVars: () => generateCssVars,
810
1558
  generateNcuCommand: () => generateNcuCommand2,
1559
+ getContrastColor: () => getContrastColor,
811
1560
  getErrorMessage: () => getErrorMessage,
812
1561
  getNextPage: () => getNextPage,
813
1562
  getPrevPage: () => getPrevPage,
814
1563
  getResponseData: () => getResponseData,
1564
+ getSystemColorScheme: () => getSystemColorScheme,
815
1565
  hasData: () => hasData,
816
1566
  hasMorePages: () => hasMorePages,
1567
+ hexToRgba: () => hexToRgba,
1568
+ injectCssVars: () => injectCssVars,
817
1569
  isClipboardAvailable: () => isClipboardAvailable,
818
1570
  isErrorResponse: () => isErrorResponse,
819
1571
  isForbidden: () => isForbidden,
@@ -827,11 +1579,20 @@ __export(client_exports, {
827
1579
  isToday: () => isToday,
828
1580
  isUnauthorized: () => isUnauthorized,
829
1581
  kebabToCamel: () => kebabToCamel,
1582
+ loadThemeFromUrl: () => loadThemeFromUrl,
1583
+ loadThemeMode: () => loadThemeMode,
1584
+ loginFormSchema: () => loginFormSchema,
1585
+ loremIpsum: () => loremIpsum,
1586
+ newsletterFormSchema: () => newsletterFormSchema,
830
1587
  packageCheck: () => packageCheck,
831
1588
  parseError: () => parseError,
832
1589
  parseFullResponse: () => parseFullResponse,
833
1590
  parseResponse: () => parseResponse,
834
1591
  readFromClipboard: () => readFromClipboard,
1592
+ registerFormSchema: () => registerFormSchema,
1593
+ removeCssVars: () => removeCssVars,
1594
+ resolveThemeMode: () => resolveThemeMode,
1595
+ saveThemeMode: () => saveThemeMode,
835
1596
  slugify: () => slugify,
836
1597
  slugifyUnique: () => slugifyUnique,
837
1598
  startOfDay: () => startOfDay,
@@ -889,7 +1650,9 @@ __export(client_exports, {
889
1650
  useSessionStorage: () => useSessionStorage_default,
890
1651
  useSet: () => useSet_default,
891
1652
  useSnackbar: () => useSnackbar_default,
1653
+ useTheme: () => useTheme,
892
1654
  useThemeDetector: () => useThemeDetector_default,
1655
+ useThemeValue: () => useThemeValue,
893
1656
  useThrottle: () => useThrottle_default,
894
1657
  useTimeout: () => useTimeout_default,
895
1658
  useToggle: () => useToggle_default,
@@ -1728,11 +2491,11 @@ function useDefault(initialValue, defaultValue) {
1728
2491
  }
1729
2492
  var useDefault_default = useDefault;
1730
2493
  function usePrevious(value, initialValue) {
1731
- const ref = react.useRef(initialValue);
2494
+ const ref2 = react.useRef(initialValue);
1732
2495
  react.useEffect(() => {
1733
- ref.current = value;
2496
+ ref2.current = value;
1734
2497
  }, [value]);
1735
- return ref.current;
2498
+ return ref2.current;
1736
2499
  }
1737
2500
  var usePrevious_default = usePrevious;
1738
2501
  function useObjectState(initialState) {
@@ -2658,7 +3421,7 @@ function useKeyPress(targetKey, callback, options = {}) {
2658
3421
  var useKeyPress_default = useKeyPress;
2659
3422
  function useHover(onHoverChange) {
2660
3423
  const [isHovered, setIsHovered] = react.useState(false);
2661
- const ref = react.useRef(null);
3424
+ const ref2 = react.useRef(null);
2662
3425
  const onMouseEnter = react.useCallback(() => {
2663
3426
  setIsHovered(true);
2664
3427
  onHoverChange?.(true);
@@ -2668,7 +3431,7 @@ function useHover(onHoverChange) {
2668
3431
  onHoverChange?.(false);
2669
3432
  }, [onHoverChange]);
2670
3433
  return {
2671
- ref,
3434
+ ref: ref2,
2672
3435
  isHovered,
2673
3436
  bind: {
2674
3437
  onMouseEnter,
@@ -2678,13 +3441,13 @@ function useHover(onHoverChange) {
2678
3441
  }
2679
3442
  var useHover_default = useHover;
2680
3443
  function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2681
- const ref = react.useRef(null);
3444
+ const ref2 = react.useRef(null);
2682
3445
  const savedCallback = react.useRef(callback);
2683
3446
  react.useEffect(() => {
2684
3447
  savedCallback.current = callback;
2685
3448
  }, [callback]);
2686
3449
  const handleClickAway = react.useCallback((event) => {
2687
- const el = ref.current;
3450
+ const el = ref2.current;
2688
3451
  if (!el || el.contains(event.target)) {
2689
3452
  return;
2690
3453
  }
@@ -2701,14 +3464,14 @@ function useClickAway(callback, events = ["mousedown", "touchstart"]) {
2701
3464
  });
2702
3465
  };
2703
3466
  }, [events, handleClickAway]);
2704
- return ref;
3467
+ return ref2;
2705
3468
  }
2706
3469
  var useClickAway_default = useClickAway;
2707
- function useOnClickOutside(ref, handler, enabled = true) {
3470
+ function useOnClickOutside(ref2, handler, enabled = true) {
2708
3471
  react.useEffect(() => {
2709
3472
  if (!enabled) return;
2710
3473
  const listener = (event) => {
2711
- const el = ref?.current;
3474
+ const el = ref2?.current;
2712
3475
  if (!el || el.contains(event.target)) {
2713
3476
  return;
2714
3477
  }
@@ -2720,7 +3483,7 @@ function useOnClickOutside(ref, handler, enabled = true) {
2720
3483
  document.removeEventListener("mousedown", listener);
2721
3484
  document.removeEventListener("touchstart", listener);
2722
3485
  };
2723
- }, [ref, handler, enabled]);
3486
+ }, [ref2, handler, enabled]);
2724
3487
  }
2725
3488
  var useOnClickOutside_default = useOnClickOutside;
2726
3489
  function useLongPress(options = {}) {
@@ -2793,7 +3556,7 @@ function useLongPress(options = {}) {
2793
3556
  var useLongPress_default = useLongPress;
2794
3557
  function useMouse(options = {}) {
2795
3558
  const { enabled = true } = options;
2796
- const ref = react.useRef(null);
3559
+ const ref2 = react.useRef(null);
2797
3560
  const [position, setPosition] = react.useState({
2798
3561
  x: 0,
2799
3562
  y: 0,
@@ -2807,8 +3570,8 @@ function useMouse(options = {}) {
2807
3570
  let elementX = 0;
2808
3571
  let elementY = 0;
2809
3572
  let isInElement = false;
2810
- if (ref.current) {
2811
- const rect = ref.current.getBoundingClientRect();
3573
+ if (ref2.current) {
3574
+ const rect = ref2.current.getBoundingClientRect();
2812
3575
  elementX = event.clientX - rect.left;
2813
3576
  elementY = event.clientY - rect.top;
2814
3577
  isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
@@ -2831,7 +3594,7 @@ function useMouse(options = {}) {
2831
3594
  };
2832
3595
  }, [enabled, handleMouseMove]);
2833
3596
  return {
2834
- ref,
3597
+ ref: ref2,
2835
3598
  ...position
2836
3599
  };
2837
3600
  }
@@ -3743,7 +4506,7 @@ function useMeasure() {
3743
4506
  y: rect.y
3744
4507
  });
3745
4508
  }, []);
3746
- const ref = react.useCallback((node) => {
4509
+ const ref2 = react.useCallback((node) => {
3747
4510
  if (observerRef.current) {
3748
4511
  observerRef.current.disconnect();
3749
4512
  observerRef.current = null;
@@ -3790,7 +4553,7 @@ function useMeasure() {
3790
4553
  }
3791
4554
  };
3792
4555
  }, []);
3793
- return { ref, dimensions, measure };
4556
+ return { ref: ref2, dimensions, measure };
3794
4557
  }
3795
4558
  var useMeasure_default = useMeasure;
3796
4559
  function useIntersectionObserver(options = {}) {
@@ -3807,7 +4570,7 @@ function useIntersectionObserver(options = {}) {
3807
4570
  const elementRef = react.useRef(null);
3808
4571
  const observerRef = react.useRef(null);
3809
4572
  const frozen = react.useRef(false);
3810
- const ref = react.useCallback(
4573
+ const ref2 = react.useCallback(
3811
4574
  (node) => {
3812
4575
  if (observerRef.current) {
3813
4576
  observerRef.current.disconnect();
@@ -3843,7 +4606,7 @@ function useIntersectionObserver(options = {}) {
3843
4606
  }
3844
4607
  };
3845
4608
  }, []);
3846
- return { ref, isIntersecting, entry };
4609
+ return { ref: ref2, isIntersecting, entry };
3847
4610
  }
3848
4611
  var useIntersectionObserver_default = useIntersectionObserver;
3849
4612
  var DEFAULT_DURATION = 4e3;
@@ -3888,75 +4651,2685 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
3888
4651
  }
3889
4652
  var useSnackbar_default = useSnackbar;
3890
4653
 
3891
- // src/shared/index.ts
3892
- var shared_exports = {};
3893
- __export(shared_exports, {
3894
- BREAKPOINTS: () => BREAKPOINTS,
3895
- CONTAINER_WIDTHS: () => CONTAINER_WIDTHS,
3896
- DATE_FORMAT: () => DATE_FORMAT,
3897
- DATE_FORMATS: () => DATE_FORMATS,
3898
- ENUMS: () => ENUMS,
3899
- ENUMS_DEFAULT: () => enums_default,
3900
- FILE_TYPE: () => FILE_TYPE,
3901
- GENDER: () => GENDER,
3902
- HTTP_STATUS: () => HTTP_STATUS,
3903
- HTTP_STATUS_MESSAGES: () => HTTP_STATUS_MESSAGES,
3904
- INTERVAL: () => INTERVAL,
3905
- LOCALE: () => LOCALE,
3906
- MEDIA_QUERIES: () => MEDIA_QUERIES,
3907
- MEDIA_QUERIES_MAX: () => MEDIA_QUERIES_MAX,
3908
- NOTIFICATION_TYPE: () => NOTIFICATION_TYPE,
3909
- ORDER_STATUS: () => ORDER_STATUS,
3910
- PAGINATION: () => PAGINATION,
3911
- PAYMENT_STATUS: () => PAYMENT_STATUS,
3912
- PERMISSION_LEVEL: () => PERMISSION_LEVEL,
3913
- PRIORITY: () => PRIORITY,
3914
- ROLE: () => ROLE,
3915
- ROLES: () => ROLES,
3916
- SORT: () => SORT,
3917
- SORT_DIRECTION: () => SORT_DIRECTION,
3918
- STATUS: () => STATUS,
3919
- SUBSCRIPTION_STATUS: () => SUBSCRIPTION_STATUS,
3920
- TASK_STATUS: () => TASK_STATUS,
3921
- THEME: () => THEME,
3922
- TOKEN_TYPES: () => TOKEN_TYPES,
3923
- USER_STATUS: () => USER_STATUS,
3924
- VALIDATION_MESSAGES: () => VALIDATION_MESSAGES,
3925
- VALIDATION_PATTERNS: () => VALIDATION_PATTERNS,
3926
- VALIDATION_RULES: () => VALIDATION_RULES,
3927
- VISIBILITY: () => VISIBILITY,
3928
- addDays: () => dateFns.addDays,
3929
- addHours: () => dateFns.addHours,
3930
- addMinutes: () => dateFns.addMinutes,
3931
- addMonths: () => dateFns.addMonths,
3932
- addTime: () => addTime,
3933
- addWeeks: () => dateFns.addWeeks,
3934
- addYears: () => dateFns.addYears,
3935
- combineDateAndTime: () => combineDateAndTime,
3936
- dateTime: () => date_time_default,
3937
- daysSince: () => daysSince,
3938
- daysUntil: () => daysUntil,
3939
- differenceInDays: () => dateFns.differenceInDays,
3940
- differenceInHours: () => dateFns.differenceInHours,
3941
- differenceInMinutes: () => dateFns.differenceInMinutes,
3942
- differenceInMonths: () => dateFns.differenceInMonths,
3943
- differenceInSeconds: () => dateFns.differenceInSeconds,
3944
- differenceInWeeks: () => dateFns.differenceInWeeks,
3945
- differenceInYears: () => dateFns.differenceInYears,
3946
- doDateRangesOverlap: () => doDateRangesOverlap,
3947
- eachDayOfInterval: () => dateFns.eachDayOfInterval,
3948
- eachMonthOfInterval: () => dateFns.eachMonthOfInterval,
3949
- eachWeekOfInterval: () => dateFns.eachWeekOfInterval,
3950
- endOfDay: () => dateFns.endOfDay,
3951
- endOfMonth: () => dateFns.endOfMonth,
3952
- endOfWeek: () => dateFns.endOfWeek,
3953
- endOfYear: () => dateFns.endOfYear,
3954
- format: () => dateFns.format,
3955
- formatDate: () => formatDate2,
3956
- formatDateInTimezone: () => formatDateInTimezone,
3957
- formatDateRange: () => formatDateRange,
3958
- formatDateTime: () => formatDateTime2,
3959
- formatDistance: () => dateFns.formatDistance,
4654
+ // src/client/web/theme/default-light-theme.ts
4655
+ var defaultLightTheme = {
4656
+ name: "default-light",
4657
+ mode: "light",
4658
+ colors: {
4659
+ brand: {
4660
+ primary: "#3b82f6",
4661
+ secondary: "#6366f1",
4662
+ accent: "#f59e0b",
4663
+ background: "#ffffff",
4664
+ foreground: "#111827"
4665
+ },
4666
+ semantic: {
4667
+ primary: "#3b82f6",
4668
+ primaryHover: "#2563eb",
4669
+ primaryActive: "#1d4ed8",
4670
+ primaryDisabled: "#93c5fd",
4671
+ secondary: "#6366f1",
4672
+ secondaryHover: "#4f46e5",
4673
+ secondaryActive: "#4338ca",
4674
+ secondaryDisabled: "#a5b4fc",
4675
+ accent: "#f59e0b",
4676
+ accentHover: "#d97706",
4677
+ success: "#22c55e",
4678
+ successHover: "#16a34a",
4679
+ warning: "#f59e0b",
4680
+ warningHover: "#d97706",
4681
+ error: "#ef4444",
4682
+ errorHover: "#dc2626",
4683
+ info: "#3b82f6",
4684
+ infoHover: "#2563eb"
4685
+ },
4686
+ background: {
4687
+ default: "#ffffff",
4688
+ paper: "#f9fafb",
4689
+ card: "#ffffff",
4690
+ overlay: "rgba(0, 0, 0, 0.5)",
4691
+ input: "#ffffff",
4692
+ disabled: "#f3f4f6",
4693
+ hover: "#f3f4f6",
4694
+ selected: "#eff6ff"
4695
+ },
4696
+ surface: {
4697
+ light: "#f9fafb",
4698
+ main: "#f3f4f6",
4699
+ dark: "#e5e7eb"
4700
+ },
4701
+ text: {
4702
+ primary: "#111827",
4703
+ secondary: "#6b7280",
4704
+ disabled: "#9ca3af",
4705
+ placeholder: "#9ca3af",
4706
+ link: "#3b82f6",
4707
+ linkHover: "#2563eb",
4708
+ inverse: "#ffffff",
4709
+ onPrimary: "#ffffff",
4710
+ onSecondary: "#ffffff"
4711
+ },
4712
+ border: {
4713
+ default: "#e5e7eb",
4714
+ light: "#f3f4f6",
4715
+ dark: "#d1d5db",
4716
+ focus: "#3b82f6",
4717
+ error: "#ef4444",
4718
+ success: "#22c55e",
4719
+ disabled: "#e5e7eb"
4720
+ }
4721
+ },
4722
+ shadows: {
4723
+ none: "none",
4724
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4725
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4726
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4727
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4728
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
4729
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4730
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
4731
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4732
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
4733
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
4734
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
4735
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
4736
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
4737
+ },
4738
+ typography: {
4739
+ fontFamily: {
4740
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
4741
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
4742
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
4743
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
4744
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
4745
+ },
4746
+ fontSize: {
4747
+ xs: "0.75rem",
4748
+ sm: "0.875rem",
4749
+ base: "1rem",
4750
+ lg: "1.125rem",
4751
+ xl: "1.25rem",
4752
+ "2xl": "1.5rem",
4753
+ "3xl": "1.875rem",
4754
+ "4xl": "2.25rem",
4755
+ "5xl": "3rem",
4756
+ "6xl": "3.75rem"
4757
+ },
4758
+ fontWeight: {
4759
+ light: 300,
4760
+ normal: 400,
4761
+ medium: 500,
4762
+ semibold: 600,
4763
+ bold: 700,
4764
+ extrabold: 800
4765
+ },
4766
+ lineHeight: {
4767
+ none: 1,
4768
+ tight: 1.25,
4769
+ snug: 1.375,
4770
+ normal: 1.5,
4771
+ relaxed: 1.625,
4772
+ loose: 2
4773
+ }
4774
+ },
4775
+ spacing: {
4776
+ 0: "0",
4777
+ px: "1px",
4778
+ 0.5: "0.125rem",
4779
+ 1: "0.25rem",
4780
+ 1.5: "0.375rem",
4781
+ 2: "0.5rem",
4782
+ 2.5: "0.625rem",
4783
+ 3: "0.75rem",
4784
+ 3.5: "0.875rem",
4785
+ 4: "1rem",
4786
+ 5: "1.25rem",
4787
+ 6: "1.5rem",
4788
+ 7: "1.75rem",
4789
+ 8: "2rem",
4790
+ 9: "2.25rem",
4791
+ 10: "2.5rem",
4792
+ 11: "2.75rem",
4793
+ 12: "3rem",
4794
+ 14: "3.5rem",
4795
+ 16: "4rem",
4796
+ 20: "5rem",
4797
+ 24: "6rem",
4798
+ 28: "7rem",
4799
+ 32: "8rem",
4800
+ 36: "9rem",
4801
+ 40: "10rem",
4802
+ 44: "11rem",
4803
+ 48: "12rem",
4804
+ 52: "13rem",
4805
+ 56: "14rem",
4806
+ 60: "15rem",
4807
+ 64: "16rem",
4808
+ 72: "18rem",
4809
+ 80: "20rem",
4810
+ 96: "24rem"
4811
+ },
4812
+ borderRadius: {
4813
+ none: "0",
4814
+ sm: "0.125rem",
4815
+ default: "0.25rem",
4816
+ md: "0.375rem",
4817
+ lg: "0.5rem",
4818
+ xl: "0.75rem",
4819
+ "2xl": "1rem",
4820
+ "3xl": "1.5rem",
4821
+ full: "9999px"
4822
+ },
4823
+ breakpoints: {
4824
+ xs: "475px",
4825
+ sm: "640px",
4826
+ md: "768px",
4827
+ lg: "1024px",
4828
+ xl: "1280px",
4829
+ "2xl": "1536px"
4830
+ },
4831
+ zIndex: {
4832
+ hide: -1,
4833
+ auto: "auto",
4834
+ base: 0,
4835
+ dropdown: 1e3,
4836
+ sticky: 1020,
4837
+ fixed: 1030,
4838
+ modalBackdrop: 1040,
4839
+ modal: 1050,
4840
+ popover: 1060,
4841
+ tooltip: 1070,
4842
+ toast: 1080
4843
+ },
4844
+ transitions: {
4845
+ none: "none",
4846
+ fast: "150ms ease-in-out",
4847
+ normal: "200ms ease-in-out",
4848
+ slow: "300ms ease-in-out",
4849
+ slower: "500ms ease-in-out",
4850
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
4851
+ transform: "transform 200ms ease-in-out",
4852
+ opacity: "opacity 200ms ease-in-out",
4853
+ shadow: "box-shadow 200ms ease-in-out",
4854
+ all: "all 200ms ease-in-out"
4855
+ },
4856
+ components: {
4857
+ button: {
4858
+ bg: "#3b82f6",
4859
+ bgHover: "#2563eb",
4860
+ bgActive: "#1d4ed8",
4861
+ bgDisabled: "#93c5fd",
4862
+ color: "#ffffff",
4863
+ colorHover: "#ffffff",
4864
+ colorDisabled: "#ffffff",
4865
+ border: "transparent",
4866
+ borderHover: "transparent",
4867
+ borderWidth: "1px",
4868
+ borderRadius: "0.375rem",
4869
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4870
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.1)",
4871
+ paddingX: "1rem",
4872
+ paddingY: "0.5rem",
4873
+ fontSize: "0.875rem",
4874
+ fontWeight: 500,
4875
+ variants: {
4876
+ primary: {
4877
+ bg: "#3b82f6",
4878
+ bgHover: "#2563eb",
4879
+ color: "#ffffff"
4880
+ },
4881
+ secondary: {
4882
+ bg: "#6366f1",
4883
+ bgHover: "#4f46e5",
4884
+ color: "#ffffff"
4885
+ },
4886
+ outline: {
4887
+ bg: "transparent",
4888
+ bgHover: "#f3f4f6",
4889
+ color: "#374151",
4890
+ border: "#d1d5db",
4891
+ borderHover: "#9ca3af"
4892
+ },
4893
+ ghost: {
4894
+ bg: "transparent",
4895
+ bgHover: "#f3f4f6",
4896
+ color: "#374151",
4897
+ shadow: "none",
4898
+ shadowHover: "none"
4899
+ },
4900
+ link: {
4901
+ bg: "transparent",
4902
+ bgHover: "transparent",
4903
+ color: "#3b82f6",
4904
+ colorHover: "#2563eb",
4905
+ shadow: "none",
4906
+ shadowHover: "none",
4907
+ paddingX: "0",
4908
+ paddingY: "0"
4909
+ },
4910
+ danger: {
4911
+ bg: "#ef4444",
4912
+ bgHover: "#dc2626",
4913
+ color: "#ffffff"
4914
+ },
4915
+ success: {
4916
+ bg: "#22c55e",
4917
+ bgHover: "#16a34a",
4918
+ color: "#ffffff"
4919
+ }
4920
+ },
4921
+ sizes: {
4922
+ xs: {
4923
+ paddingX: "0.5rem",
4924
+ paddingY: "0.25rem",
4925
+ fontSize: "0.75rem"
4926
+ },
4927
+ sm: {
4928
+ paddingX: "0.75rem",
4929
+ paddingY: "0.375rem",
4930
+ fontSize: "0.875rem"
4931
+ },
4932
+ md: {
4933
+ paddingX: "1rem",
4934
+ paddingY: "0.5rem",
4935
+ fontSize: "0.875rem"
4936
+ },
4937
+ lg: {
4938
+ paddingX: "1.25rem",
4939
+ paddingY: "0.625rem",
4940
+ fontSize: "1rem"
4941
+ },
4942
+ xl: {
4943
+ paddingX: "1.5rem",
4944
+ paddingY: "0.75rem",
4945
+ fontSize: "1.125rem"
4946
+ }
4947
+ }
4948
+ },
4949
+ input: {
4950
+ bg: "#ffffff",
4951
+ bgFocus: "#ffffff",
4952
+ bgDisabled: "#f3f4f6",
4953
+ bgError: "#fef2f2",
4954
+ color: "#111827",
4955
+ colorPlaceholder: "#9ca3af",
4956
+ colorDisabled: "#9ca3af",
4957
+ border: "#d1d5db",
4958
+ borderFocus: "#3b82f6",
4959
+ borderError: "#ef4444",
4960
+ borderWidth: "1px",
4961
+ borderRadius: "0.375rem",
4962
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
4963
+ shadowFocus: "0 0 0 3px rgb(59 130 246 / 0.1)",
4964
+ paddingX: "0.75rem",
4965
+ paddingY: "0.5rem",
4966
+ fontSize: "0.875rem",
4967
+ labelColor: "#374151",
4968
+ labelFontSize: "0.875rem",
4969
+ labelFontWeight: 500,
4970
+ helperColor: "#6b7280",
4971
+ errorColor: "#ef4444",
4972
+ sizes: {
4973
+ sm: {
4974
+ paddingX: "0.5rem",
4975
+ paddingY: "0.375rem",
4976
+ fontSize: "0.75rem"
4977
+ },
4978
+ md: {
4979
+ paddingX: "0.75rem",
4980
+ paddingY: "0.5rem",
4981
+ fontSize: "0.875rem"
4982
+ },
4983
+ lg: {
4984
+ paddingX: "1rem",
4985
+ paddingY: "0.625rem",
4986
+ fontSize: "1rem"
4987
+ }
4988
+ }
4989
+ },
4990
+ card: {
4991
+ bg: "#ffffff",
4992
+ bgHover: "#ffffff",
4993
+ border: "#e5e7eb",
4994
+ borderWidth: "1px",
4995
+ borderRadius: "0.5rem",
4996
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
4997
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
4998
+ padding: "1.5rem",
4999
+ headerBg: "#f9fafb",
5000
+ headerBorder: "#e5e7eb",
5001
+ headerPadding: "1rem 1.5rem",
5002
+ footerBg: "#f9fafb",
5003
+ footerBorder: "#e5e7eb",
5004
+ footerPadding: "1rem 1.5rem"
5005
+ },
5006
+ header: {
5007
+ bg: "#ffffff",
5008
+ bgScrolled: "rgba(255, 255, 255, 0.95)",
5009
+ color: "#111827",
5010
+ border: "#e5e7eb",
5011
+ shadow: "none",
5012
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
5013
+ height: "4rem",
5014
+ paddingX: "1.5rem",
5015
+ logoHeight: "2rem",
5016
+ navColor: "#374151",
5017
+ navColorHover: "#111827",
5018
+ navColorActive: "#3b82f6",
5019
+ navFontSize: "0.875rem",
5020
+ navFontWeight: 500,
5021
+ mobileMenuBg: "#ffffff",
5022
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)"
5023
+ },
5024
+ footer: {
5025
+ bg: "#111827",
5026
+ color: "#d1d5db",
5027
+ colorMuted: "#9ca3af",
5028
+ border: "#374151",
5029
+ padding: "4rem 1.5rem",
5030
+ linkColor: "#d1d5db",
5031
+ linkColorHover: "#ffffff",
5032
+ headingColor: "#ffffff",
5033
+ headingFontSize: "1rem",
5034
+ headingFontWeight: 600,
5035
+ copyrightBg: "#0f172a",
5036
+ copyrightColor: "#9ca3af"
5037
+ },
5038
+ banner: {
5039
+ bg: "#eff6ff",
5040
+ color: "#1e40af",
5041
+ border: "#bfdbfe",
5042
+ borderRadius: "0.5rem",
5043
+ padding: "1rem 1.5rem",
5044
+ shadow: "none",
5045
+ closeBg: "transparent",
5046
+ closeColor: "#1e40af",
5047
+ variants: {
5048
+ info: {
5049
+ bg: "#eff6ff",
5050
+ color: "#1e40af",
5051
+ border: "#bfdbfe"
5052
+ },
5053
+ success: {
5054
+ bg: "#f0fdf4",
5055
+ color: "#166534",
5056
+ border: "#bbf7d0"
5057
+ },
5058
+ warning: {
5059
+ bg: "#fffbeb",
5060
+ color: "#92400e",
5061
+ border: "#fde68a"
5062
+ },
5063
+ error: {
5064
+ bg: "#fef2f2",
5065
+ color: "#991b1b",
5066
+ border: "#fecaca"
5067
+ },
5068
+ promo: {
5069
+ bg: "#faf5ff",
5070
+ color: "#6b21a8",
5071
+ border: "#e9d5ff"
5072
+ }
5073
+ }
5074
+ },
5075
+ loader: {
5076
+ color: "#3b82f6",
5077
+ colorSecondary: "#e5e7eb",
5078
+ size: "2.5rem",
5079
+ borderWidth: "3px",
5080
+ overlayBg: "rgba(255, 255, 255, 0.8)",
5081
+ overlayOpacity: 1,
5082
+ sizes: {
5083
+ xs: "1rem",
5084
+ sm: "1.5rem",
5085
+ md: "2.5rem",
5086
+ lg: "3.5rem",
5087
+ xl: "5rem"
5088
+ }
5089
+ },
5090
+ modal: {
5091
+ bg: "#ffffff",
5092
+ color: "#111827",
5093
+ border: "#e5e7eb",
5094
+ borderRadius: "0.5rem",
5095
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
5096
+ padding: "1.5rem",
5097
+ overlayBg: "rgba(0, 0, 0, 0.5)",
5098
+ overlayOpacity: 1,
5099
+ headerBg: "#ffffff",
5100
+ headerBorder: "#e5e7eb",
5101
+ headerPadding: "1rem 1.5rem",
5102
+ footerBg: "#f9fafb",
5103
+ footerBorder: "#e5e7eb",
5104
+ footerPadding: "1rem 1.5rem",
5105
+ closeBg: "transparent",
5106
+ closeColor: "#6b7280",
5107
+ closeHoverBg: "#f3f4f6",
5108
+ sizes: {
5109
+ sm: "24rem",
5110
+ md: "32rem",
5111
+ lg: "48rem",
5112
+ xl: "64rem",
5113
+ full: "100%"
5114
+ }
5115
+ },
5116
+ toast: {
5117
+ bg: "#ffffff",
5118
+ color: "#111827",
5119
+ border: "#e5e7eb",
5120
+ borderRadius: "0.5rem",
5121
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
5122
+ padding: "1rem",
5123
+ variants: {
5124
+ success: {
5125
+ bg: "#f0fdf4",
5126
+ color: "#166534",
5127
+ border: "#bbf7d0"
5128
+ },
5129
+ error: {
5130
+ bg: "#fef2f2",
5131
+ color: "#991b1b",
5132
+ border: "#fecaca"
5133
+ },
5134
+ warning: {
5135
+ bg: "#fffbeb",
5136
+ color: "#92400e",
5137
+ border: "#fde68a"
5138
+ },
5139
+ info: {
5140
+ bg: "#eff6ff",
5141
+ color: "#1e40af",
5142
+ border: "#bfdbfe"
5143
+ }
5144
+ }
5145
+ },
5146
+ newsletter: {
5147
+ bg: "#f9fafb",
5148
+ color: "#111827",
5149
+ border: "#e5e7eb",
5150
+ borderRadius: "0.5rem",
5151
+ padding: "2rem",
5152
+ titleColor: "#111827",
5153
+ titleFontSize: "1.5rem",
5154
+ descColor: "#6b7280",
5155
+ descFontSize: "1rem",
5156
+ inputBg: "#ffffff",
5157
+ inputBorder: "#d1d5db",
5158
+ buttonBg: "#3b82f6",
5159
+ buttonColor: "#ffffff"
5160
+ }
5161
+ }
5162
+ };
5163
+
5164
+ // src/client/web/theme/default-dark-theme.ts
5165
+ var defaultDarkTheme = {
5166
+ name: "default-dark",
5167
+ mode: "dark",
5168
+ colors: {
5169
+ brand: {
5170
+ primary: "#60a5fa",
5171
+ secondary: "#818cf8",
5172
+ accent: "#fbbf24",
5173
+ background: "#0f172a",
5174
+ foreground: "#f8fafc"
5175
+ },
5176
+ semantic: {
5177
+ primary: "#60a5fa",
5178
+ primaryHover: "#3b82f6",
5179
+ primaryActive: "#2563eb",
5180
+ primaryDisabled: "#1e3a5f",
5181
+ secondary: "#818cf8",
5182
+ secondaryHover: "#6366f1",
5183
+ secondaryActive: "#4f46e5",
5184
+ secondaryDisabled: "#312e81",
5185
+ accent: "#fbbf24",
5186
+ accentHover: "#f59e0b",
5187
+ success: "#4ade80",
5188
+ successHover: "#22c55e",
5189
+ warning: "#fbbf24",
5190
+ warningHover: "#f59e0b",
5191
+ error: "#f87171",
5192
+ errorHover: "#ef4444",
5193
+ info: "#60a5fa",
5194
+ infoHover: "#3b82f6"
5195
+ },
5196
+ background: {
5197
+ default: "#0f172a",
5198
+ paper: "#1e293b",
5199
+ card: "#1e293b",
5200
+ overlay: "rgba(0, 0, 0, 0.7)",
5201
+ input: "#1e293b",
5202
+ disabled: "#334155",
5203
+ hover: "#334155",
5204
+ selected: "#1e3a5f"
5205
+ },
5206
+ surface: {
5207
+ light: "#334155",
5208
+ main: "#1e293b",
5209
+ dark: "#0f172a"
5210
+ },
5211
+ text: {
5212
+ primary: "#f8fafc",
5213
+ secondary: "#94a3b8",
5214
+ disabled: "#64748b",
5215
+ placeholder: "#64748b",
5216
+ link: "#60a5fa",
5217
+ linkHover: "#3b82f6",
5218
+ inverse: "#0f172a",
5219
+ onPrimary: "#0f172a",
5220
+ onSecondary: "#0f172a"
5221
+ },
5222
+ border: {
5223
+ default: "#334155",
5224
+ light: "#475569",
5225
+ dark: "#1e293b",
5226
+ focus: "#60a5fa",
5227
+ error: "#f87171",
5228
+ success: "#4ade80",
5229
+ disabled: "#334155"
5230
+ }
5231
+ },
5232
+ shadows: {
5233
+ none: "none",
5234
+ xs: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
5235
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4)",
5236
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",
5237
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",
5238
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)",
5239
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.6)",
5240
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.3)",
5241
+ button: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
5242
+ buttonHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
5243
+ card: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
5244
+ cardHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
5245
+ modal: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
5246
+ dropdown: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
5247
+ },
5248
+ typography: {
5249
+ fontFamily: {
5250
+ sans: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
5251
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
5252
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
5253
+ heading: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
5254
+ body: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
5255
+ },
5256
+ fontSize: {
5257
+ xs: "0.75rem",
5258
+ sm: "0.875rem",
5259
+ base: "1rem",
5260
+ lg: "1.125rem",
5261
+ xl: "1.25rem",
5262
+ "2xl": "1.5rem",
5263
+ "3xl": "1.875rem",
5264
+ "4xl": "2.25rem",
5265
+ "5xl": "3rem",
5266
+ "6xl": "3.75rem"
5267
+ },
5268
+ fontWeight: {
5269
+ light: 300,
5270
+ normal: 400,
5271
+ medium: 500,
5272
+ semibold: 600,
5273
+ bold: 700,
5274
+ extrabold: 800
5275
+ },
5276
+ lineHeight: {
5277
+ none: 1,
5278
+ tight: 1.25,
5279
+ snug: 1.375,
5280
+ normal: 1.5,
5281
+ relaxed: 1.625,
5282
+ loose: 2
5283
+ }
5284
+ },
5285
+ spacing: {
5286
+ 0: "0",
5287
+ px: "1px",
5288
+ 0.5: "0.125rem",
5289
+ 1: "0.25rem",
5290
+ 1.5: "0.375rem",
5291
+ 2: "0.5rem",
5292
+ 2.5: "0.625rem",
5293
+ 3: "0.75rem",
5294
+ 3.5: "0.875rem",
5295
+ 4: "1rem",
5296
+ 5: "1.25rem",
5297
+ 6: "1.5rem",
5298
+ 7: "1.75rem",
5299
+ 8: "2rem",
5300
+ 9: "2.25rem",
5301
+ 10: "2.5rem",
5302
+ 11: "2.75rem",
5303
+ 12: "3rem",
5304
+ 14: "3.5rem",
5305
+ 16: "4rem",
5306
+ 20: "5rem",
5307
+ 24: "6rem",
5308
+ 28: "7rem",
5309
+ 32: "8rem",
5310
+ 36: "9rem",
5311
+ 40: "10rem",
5312
+ 44: "11rem",
5313
+ 48: "12rem",
5314
+ 52: "13rem",
5315
+ 56: "14rem",
5316
+ 60: "15rem",
5317
+ 64: "16rem",
5318
+ 72: "18rem",
5319
+ 80: "20rem",
5320
+ 96: "24rem"
5321
+ },
5322
+ borderRadius: {
5323
+ none: "0",
5324
+ sm: "0.125rem",
5325
+ default: "0.25rem",
5326
+ md: "0.375rem",
5327
+ lg: "0.5rem",
5328
+ xl: "0.75rem",
5329
+ "2xl": "1rem",
5330
+ "3xl": "1.5rem",
5331
+ full: "9999px"
5332
+ },
5333
+ breakpoints: {
5334
+ xs: "475px",
5335
+ sm: "640px",
5336
+ md: "768px",
5337
+ lg: "1024px",
5338
+ xl: "1280px",
5339
+ "2xl": "1536px"
5340
+ },
5341
+ zIndex: {
5342
+ hide: -1,
5343
+ auto: "auto",
5344
+ base: 0,
5345
+ dropdown: 1e3,
5346
+ sticky: 1020,
5347
+ fixed: 1030,
5348
+ modalBackdrop: 1040,
5349
+ modal: 1050,
5350
+ popover: 1060,
5351
+ tooltip: 1070,
5352
+ toast: 1080
5353
+ },
5354
+ transitions: {
5355
+ none: "none",
5356
+ fast: "150ms ease-in-out",
5357
+ normal: "200ms ease-in-out",
5358
+ slow: "300ms ease-in-out",
5359
+ slower: "500ms ease-in-out",
5360
+ colors: "color 200ms ease-in-out, background-color 200ms ease-in-out, border-color 200ms ease-in-out",
5361
+ transform: "transform 200ms ease-in-out",
5362
+ opacity: "opacity 200ms ease-in-out",
5363
+ shadow: "box-shadow 200ms ease-in-out",
5364
+ all: "all 200ms ease-in-out"
5365
+ },
5366
+ components: {
5367
+ button: {
5368
+ bg: "#60a5fa",
5369
+ bgHover: "#3b82f6",
5370
+ bgActive: "#2563eb",
5371
+ bgDisabled: "#1e3a5f",
5372
+ color: "#0f172a",
5373
+ colorHover: "#0f172a",
5374
+ colorDisabled: "#64748b",
5375
+ border: "transparent",
5376
+ borderHover: "transparent",
5377
+ borderWidth: "1px",
5378
+ borderRadius: "0.375rem",
5379
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
5380
+ shadowHover: "0 4px 6px -1px rgb(0 0 0 / 0.4)",
5381
+ paddingX: "1rem",
5382
+ paddingY: "0.5rem",
5383
+ fontSize: "0.875rem",
5384
+ fontWeight: 500,
5385
+ variants: {
5386
+ primary: {
5387
+ bg: "#60a5fa",
5388
+ bgHover: "#3b82f6",
5389
+ color: "#0f172a"
5390
+ },
5391
+ secondary: {
5392
+ bg: "#818cf8",
5393
+ bgHover: "#6366f1",
5394
+ color: "#0f172a"
5395
+ },
5396
+ outline: {
5397
+ bg: "transparent",
5398
+ bgHover: "#334155",
5399
+ color: "#f8fafc",
5400
+ border: "#475569",
5401
+ borderHover: "#64748b"
5402
+ },
5403
+ ghost: {
5404
+ bg: "transparent",
5405
+ bgHover: "#334155",
5406
+ color: "#f8fafc",
5407
+ shadow: "none",
5408
+ shadowHover: "none"
5409
+ },
5410
+ link: {
5411
+ bg: "transparent",
5412
+ bgHover: "transparent",
5413
+ color: "#60a5fa",
5414
+ colorHover: "#3b82f6",
5415
+ shadow: "none",
5416
+ shadowHover: "none",
5417
+ paddingX: "0",
5418
+ paddingY: "0"
5419
+ },
5420
+ danger: {
5421
+ bg: "#f87171",
5422
+ bgHover: "#ef4444",
5423
+ color: "#0f172a"
5424
+ },
5425
+ success: {
5426
+ bg: "#4ade80",
5427
+ bgHover: "#22c55e",
5428
+ color: "#0f172a"
5429
+ }
5430
+ },
5431
+ sizes: {
5432
+ xs: {
5433
+ paddingX: "0.5rem",
5434
+ paddingY: "0.25rem",
5435
+ fontSize: "0.75rem"
5436
+ },
5437
+ sm: {
5438
+ paddingX: "0.75rem",
5439
+ paddingY: "0.375rem",
5440
+ fontSize: "0.875rem"
5441
+ },
5442
+ md: {
5443
+ paddingX: "1rem",
5444
+ paddingY: "0.5rem",
5445
+ fontSize: "0.875rem"
5446
+ },
5447
+ lg: {
5448
+ paddingX: "1.25rem",
5449
+ paddingY: "0.625rem",
5450
+ fontSize: "1rem"
5451
+ },
5452
+ xl: {
5453
+ paddingX: "1.5rem",
5454
+ paddingY: "0.75rem",
5455
+ fontSize: "1.125rem"
5456
+ }
5457
+ }
5458
+ },
5459
+ input: {
5460
+ bg: "#1e293b",
5461
+ bgFocus: "#1e293b",
5462
+ bgDisabled: "#334155",
5463
+ bgError: "#450a0a",
5464
+ color: "#f8fafc",
5465
+ colorPlaceholder: "#64748b",
5466
+ colorDisabled: "#64748b",
5467
+ border: "#475569",
5468
+ borderFocus: "#60a5fa",
5469
+ borderError: "#f87171",
5470
+ borderWidth: "1px",
5471
+ borderRadius: "0.375rem",
5472
+ shadow: "0 1px 2px 0 rgb(0 0 0 / 0.3)",
5473
+ shadowFocus: "0 0 0 3px rgb(96 165 250 / 0.2)",
5474
+ paddingX: "0.75rem",
5475
+ paddingY: "0.5rem",
5476
+ fontSize: "0.875rem",
5477
+ labelColor: "#e2e8f0",
5478
+ labelFontSize: "0.875rem",
5479
+ labelFontWeight: 500,
5480
+ helperColor: "#94a3b8",
5481
+ errorColor: "#f87171",
5482
+ sizes: {
5483
+ sm: {
5484
+ paddingX: "0.5rem",
5485
+ paddingY: "0.375rem",
5486
+ fontSize: "0.75rem"
5487
+ },
5488
+ md: {
5489
+ paddingX: "0.75rem",
5490
+ paddingY: "0.5rem",
5491
+ fontSize: "0.875rem"
5492
+ },
5493
+ lg: {
5494
+ paddingX: "1rem",
5495
+ paddingY: "0.625rem",
5496
+ fontSize: "1rem"
5497
+ }
5498
+ }
5499
+ },
5500
+ card: {
5501
+ bg: "#1e293b",
5502
+ bgHover: "#1e293b",
5503
+ border: "#334155",
5504
+ borderWidth: "1px",
5505
+ borderRadius: "0.5rem",
5506
+ shadow: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
5507
+ shadowHover: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
5508
+ padding: "1.5rem",
5509
+ headerBg: "#0f172a",
5510
+ headerBorder: "#334155",
5511
+ headerPadding: "1rem 1.5rem",
5512
+ footerBg: "#0f172a",
5513
+ footerBorder: "#334155",
5514
+ footerPadding: "1rem 1.5rem"
5515
+ },
5516
+ header: {
5517
+ bg: "#0f172a",
5518
+ bgScrolled: "rgba(15, 23, 42, 0.95)",
5519
+ color: "#f8fafc",
5520
+ border: "#334155",
5521
+ shadow: "none",
5522
+ shadowScrolled: "0 1px 3px 0 rgb(0 0 0 / 0.4)",
5523
+ height: "4rem",
5524
+ paddingX: "1.5rem",
5525
+ logoHeight: "2rem",
5526
+ navColor: "#94a3b8",
5527
+ navColorHover: "#f8fafc",
5528
+ navColorActive: "#60a5fa",
5529
+ navFontSize: "0.875rem",
5530
+ navFontWeight: 500,
5531
+ mobileMenuBg: "#1e293b",
5532
+ mobileMenuShadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)"
5533
+ },
5534
+ footer: {
5535
+ bg: "#020617",
5536
+ color: "#94a3b8",
5537
+ colorMuted: "#64748b",
5538
+ border: "#1e293b",
5539
+ padding: "4rem 1.5rem",
5540
+ linkColor: "#94a3b8",
5541
+ linkColorHover: "#f8fafc",
5542
+ headingColor: "#f8fafc",
5543
+ headingFontSize: "1rem",
5544
+ headingFontWeight: 600,
5545
+ copyrightBg: "#0f172a",
5546
+ copyrightColor: "#64748b"
5547
+ },
5548
+ banner: {
5549
+ bg: "#1e3a5f",
5550
+ color: "#bfdbfe",
5551
+ border: "#3b82f6",
5552
+ borderRadius: "0.5rem",
5553
+ padding: "1rem 1.5rem",
5554
+ shadow: "none",
5555
+ closeBg: "transparent",
5556
+ closeColor: "#bfdbfe",
5557
+ variants: {
5558
+ info: {
5559
+ bg: "#1e3a5f",
5560
+ color: "#bfdbfe",
5561
+ border: "#3b82f6"
5562
+ },
5563
+ success: {
5564
+ bg: "#14532d",
5565
+ color: "#bbf7d0",
5566
+ border: "#22c55e"
5567
+ },
5568
+ warning: {
5569
+ bg: "#78350f",
5570
+ color: "#fde68a",
5571
+ border: "#f59e0b"
5572
+ },
5573
+ error: {
5574
+ bg: "#7f1d1d",
5575
+ color: "#fecaca",
5576
+ border: "#ef4444"
5577
+ },
5578
+ promo: {
5579
+ bg: "#581c87",
5580
+ color: "#e9d5ff",
5581
+ border: "#a855f7"
5582
+ }
5583
+ }
5584
+ },
5585
+ loader: {
5586
+ color: "#60a5fa",
5587
+ colorSecondary: "#334155",
5588
+ size: "2.5rem",
5589
+ borderWidth: "3px",
5590
+ overlayBg: "rgba(15, 23, 42, 0.8)",
5591
+ overlayOpacity: 1,
5592
+ sizes: {
5593
+ xs: "1rem",
5594
+ sm: "1.5rem",
5595
+ md: "2.5rem",
5596
+ lg: "3.5rem",
5597
+ xl: "5rem"
5598
+ }
5599
+ },
5600
+ modal: {
5601
+ bg: "#1e293b",
5602
+ color: "#f8fafc",
5603
+ border: "#334155",
5604
+ borderRadius: "0.5rem",
5605
+ shadow: "0 25px 50px -12px rgb(0 0 0 / 0.6)",
5606
+ padding: "1.5rem",
5607
+ overlayBg: "rgba(0, 0, 0, 0.7)",
5608
+ overlayOpacity: 1,
5609
+ headerBg: "#1e293b",
5610
+ headerBorder: "#334155",
5611
+ headerPadding: "1rem 1.5rem",
5612
+ footerBg: "#0f172a",
5613
+ footerBorder: "#334155",
5614
+ footerPadding: "1rem 1.5rem",
5615
+ closeBg: "transparent",
5616
+ closeColor: "#94a3b8",
5617
+ closeHoverBg: "#334155",
5618
+ sizes: {
5619
+ sm: "24rem",
5620
+ md: "32rem",
5621
+ lg: "48rem",
5622
+ xl: "64rem",
5623
+ full: "100%"
5624
+ }
5625
+ },
5626
+ toast: {
5627
+ bg: "#1e293b",
5628
+ color: "#f8fafc",
5629
+ border: "#334155",
5630
+ borderRadius: "0.5rem",
5631
+ shadow: "0 10px 15px -3px rgb(0 0 0 / 0.4)",
5632
+ padding: "1rem",
5633
+ variants: {
5634
+ success: {
5635
+ bg: "#14532d",
5636
+ color: "#bbf7d0",
5637
+ border: "#22c55e"
5638
+ },
5639
+ error: {
5640
+ bg: "#7f1d1d",
5641
+ color: "#fecaca",
5642
+ border: "#ef4444"
5643
+ },
5644
+ warning: {
5645
+ bg: "#78350f",
5646
+ color: "#fde68a",
5647
+ border: "#f59e0b"
5648
+ },
5649
+ info: {
5650
+ bg: "#1e3a5f",
5651
+ color: "#bfdbfe",
5652
+ border: "#3b82f6"
5653
+ }
5654
+ }
5655
+ },
5656
+ newsletter: {
5657
+ bg: "#1e293b",
5658
+ color: "#f8fafc",
5659
+ border: "#334155",
5660
+ borderRadius: "0.5rem",
5661
+ padding: "2rem",
5662
+ titleColor: "#f8fafc",
5663
+ titleFontSize: "1.5rem",
5664
+ descColor: "#94a3b8",
5665
+ descFontSize: "1rem",
5666
+ inputBg: "#0f172a",
5667
+ inputBorder: "#475569",
5668
+ buttonBg: "#60a5fa",
5669
+ buttonColor: "#0f172a"
5670
+ }
5671
+ }
5672
+ };
5673
+
5674
+ // src/client/web/theme/theme-utils.ts
5675
+ function deepMerge2(target, source) {
5676
+ const output = { ...target };
5677
+ for (const key in source) {
5678
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
5679
+ const sourceValue = source[key];
5680
+ const targetValue = target[key];
5681
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
5682
+ output[key] = deepMerge2(
5683
+ targetValue,
5684
+ sourceValue
5685
+ );
5686
+ } else if (sourceValue !== void 0) {
5687
+ output[key] = sourceValue;
5688
+ }
5689
+ }
5690
+ }
5691
+ return output;
5692
+ }
5693
+ function createThemeFromBrand(brand, baseTheme = defaultLightTheme) {
5694
+ const { colors: colors2 } = brand;
5695
+ const brandOverrides = {
5696
+ brand,
5697
+ colors: {
5698
+ brand: {
5699
+ primary: colors2.primary,
5700
+ secondary: colors2.secondary,
5701
+ accent: colors2.accent || colors2.primary,
5702
+ background: colors2.background || baseTheme.colors.background.default,
5703
+ foreground: colors2.foreground || baseTheme.colors.text.primary
5704
+ },
5705
+ semantic: {
5706
+ primary: colors2.primary,
5707
+ primaryHover: adjustColor(colors2.primary, -10),
5708
+ primaryActive: adjustColor(colors2.primary, -20),
5709
+ primaryDisabled: adjustColor(colors2.primary, 40),
5710
+ secondary: colors2.secondary,
5711
+ secondaryHover: adjustColor(colors2.secondary, -10),
5712
+ secondaryActive: adjustColor(colors2.secondary, -20),
5713
+ secondaryDisabled: adjustColor(colors2.secondary, 40),
5714
+ accent: colors2.accent || colors2.primary,
5715
+ accentHover: adjustColor(colors2.accent || colors2.primary, -10)
5716
+ }
5717
+ },
5718
+ components: {
5719
+ button: {
5720
+ bg: colors2.primary,
5721
+ bgHover: adjustColor(colors2.primary, -10),
5722
+ bgActive: adjustColor(colors2.primary, -20),
5723
+ variants: {
5724
+ primary: {
5725
+ bg: colors2.primary,
5726
+ bgHover: adjustColor(colors2.primary, -10)
5727
+ },
5728
+ secondary: {
5729
+ bg: colors2.secondary,
5730
+ bgHover: adjustColor(colors2.secondary, -10)
5731
+ }
5732
+ }
5733
+ },
5734
+ input: {
5735
+ borderFocus: colors2.primary
5736
+ },
5737
+ header: {
5738
+ navColorActive: colors2.primary
5739
+ },
5740
+ loader: {
5741
+ color: colors2.primary
5742
+ },
5743
+ newsletter: {
5744
+ buttonBg: colors2.primary
5745
+ }
5746
+ }
5747
+ };
5748
+ return deepMerge2(baseTheme, brandOverrides);
5749
+ }
5750
+ function adjustColor(hex, percent) {
5751
+ hex = hex.replace(/^#/, "");
5752
+ let r = parseInt(hex.substring(0, 2), 16);
5753
+ let g = parseInt(hex.substring(2, 4), 16);
5754
+ let b = parseInt(hex.substring(4, 6), 16);
5755
+ r = Math.min(255, Math.max(0, r + r * percent / 100));
5756
+ g = Math.min(255, Math.max(0, g + g * percent / 100));
5757
+ b = Math.min(255, Math.max(0, b + b * percent / 100));
5758
+ const toHex = (n) => Math.round(n).toString(16).padStart(2, "0");
5759
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
5760
+ }
5761
+ function hexToRgba(hex, alpha = 1) {
5762
+ hex = hex.replace(/^#/, "");
5763
+ const r = parseInt(hex.substring(0, 2), 16);
5764
+ const g = parseInt(hex.substring(2, 4), 16);
5765
+ const b = parseInt(hex.substring(4, 6), 16);
5766
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
5767
+ }
5768
+ function getContrastColor(hex) {
5769
+ hex = hex.replace(/^#/, "");
5770
+ const r = parseInt(hex.substring(0, 2), 16);
5771
+ const g = parseInt(hex.substring(2, 4), 16);
5772
+ const b = parseInt(hex.substring(4, 6), 16);
5773
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
5774
+ return luminance > 0.5 ? "#000000" : "#ffffff";
5775
+ }
5776
+ function flattenToCssVars(obj, prefix = "--ec") {
5777
+ const result = {};
5778
+ function flatten(current, path2 = []) {
5779
+ for (const key in current) {
5780
+ if (Object.prototype.hasOwnProperty.call(current, key)) {
5781
+ const value = current[key];
5782
+ const newPath = [...path2, key];
5783
+ const varName = `${prefix}-${newPath.join("-")}`;
5784
+ if (value && typeof value === "object" && !Array.isArray(value)) {
5785
+ flatten(value, newPath);
5786
+ } else if (typeof value === "string" || typeof value === "number") {
5787
+ result[varName] = String(value);
5788
+ }
5789
+ }
5790
+ }
5791
+ }
5792
+ flatten(obj);
5793
+ return result;
5794
+ }
5795
+ function generateCssVars(theme, prefix = "--ec") {
5796
+ const cssVars = flattenToCssVars(theme, prefix);
5797
+ return Object.entries(cssVars).map(([key, value]) => `${key}: ${value};`).join("\n");
5798
+ }
5799
+ function injectCssVars(theme, prefix = "--ec") {
5800
+ if (typeof document === "undefined") return;
5801
+ const cssVars = flattenToCssVars(theme, prefix);
5802
+ const root = document.documentElement;
5803
+ for (const [key, value] of Object.entries(cssVars)) {
5804
+ root.style.setProperty(key, value);
5805
+ }
5806
+ }
5807
+ function removeCssVars(prefix = "--ec") {
5808
+ if (typeof document === "undefined") return;
5809
+ const root = document.documentElement;
5810
+ const style = root.style;
5811
+ for (let i = style.length - 1; i >= 0; i--) {
5812
+ const name = style[i];
5813
+ if (name.startsWith(prefix)) {
5814
+ root.style.removeProperty(name);
5815
+ }
5816
+ }
5817
+ }
5818
+ async function loadThemeFromUrl(url) {
5819
+ try {
5820
+ const response = await fetch(url, {
5821
+ headers: {
5822
+ Accept: "application/json"
5823
+ }
5824
+ });
5825
+ if (!response.ok) {
5826
+ console.error(`Failed to load theme from ${url}: ${response.status}`);
5827
+ return null;
5828
+ }
5829
+ const themeData = await response.json();
5830
+ return themeData;
5831
+ } catch (error) {
5832
+ console.error(`Error loading theme from ${url}:`, error);
5833
+ return null;
5834
+ }
5835
+ }
5836
+ async function createTheme(config = {}) {
5837
+ let lightTheme = { ...defaultLightTheme };
5838
+ let darkTheme = { ...defaultDarkTheme };
5839
+ if (config.themeUrl) {
5840
+ const urlTheme = await loadThemeFromUrl(config.themeUrl);
5841
+ if (urlTheme) {
5842
+ lightTheme = deepMerge2(lightTheme, urlTheme);
5843
+ darkTheme = deepMerge2(darkTheme, urlTheme);
5844
+ }
5845
+ }
5846
+ if (config.brandIdentity) {
5847
+ lightTheme = createThemeFromBrand(config.brandIdentity, lightTheme);
5848
+ darkTheme = createThemeFromBrand(config.brandIdentity, darkTheme);
5849
+ }
5850
+ if (config.light) {
5851
+ lightTheme = deepMerge2(lightTheme, config.light);
5852
+ }
5853
+ if (config.dark) {
5854
+ darkTheme = deepMerge2(darkTheme, config.dark);
5855
+ }
5856
+ return { light: lightTheme, dark: darkTheme };
5857
+ }
5858
+ var DEFAULT_STORAGE_KEY = "ec-theme-mode";
5859
+ function saveThemeMode(mode, storageKey = DEFAULT_STORAGE_KEY) {
5860
+ if (typeof localStorage === "undefined") return;
5861
+ try {
5862
+ localStorage.setItem(storageKey, mode);
5863
+ } catch (error) {
5864
+ console.error("Failed to save theme mode:", error);
5865
+ }
5866
+ }
5867
+ function loadThemeMode(storageKey = DEFAULT_STORAGE_KEY) {
5868
+ if (typeof localStorage === "undefined") return null;
5869
+ try {
5870
+ const mode = localStorage.getItem(storageKey);
5871
+ if (mode === "light" || mode === "dark" || mode === "system") {
5872
+ return mode;
5873
+ }
5874
+ return null;
5875
+ } catch (error) {
5876
+ console.error("Failed to load theme mode:", error);
5877
+ return null;
5878
+ }
5879
+ }
5880
+ function getSystemColorScheme() {
5881
+ if (typeof window === "undefined") return "light";
5882
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5883
+ }
5884
+ function resolveThemeMode(mode) {
5885
+ if (mode === "system") {
5886
+ return getSystemColorScheme();
5887
+ }
5888
+ return mode;
5889
+ }
5890
+ var ThemeContext = react.createContext(null);
5891
+ function useTheme() {
5892
+ const context = react.useContext(ThemeContext);
5893
+ if (!context) {
5894
+ throw new Error("useTheme must be used within a ThemeProvider");
5895
+ }
5896
+ return context;
5897
+ }
5898
+ function ThemeProvider({
5899
+ children,
5900
+ config = {},
5901
+ initialTheme
5902
+ }) {
5903
+ const {
5904
+ defaultMode = "system",
5905
+ themeUrl,
5906
+ light: lightOverrides,
5907
+ dark: darkOverrides,
5908
+ brandIdentity,
5909
+ enableSystemTheme = true,
5910
+ persistTheme = true,
5911
+ storageKey = "ec-theme-mode",
5912
+ cssVarPrefix = "--ec"
5913
+ } = config;
5914
+ const [mode, setModeState] = react.useState(() => {
5915
+ if (persistTheme && typeof window !== "undefined") {
5916
+ const savedMode = loadThemeMode(storageKey);
5917
+ if (savedMode) return savedMode;
5918
+ }
5919
+ return defaultMode;
5920
+ });
5921
+ const [lightTheme, setLightTheme] = react.useState(() => {
5922
+ if (initialTheme && initialTheme.mode === "light") return initialTheme;
5923
+ let theme2 = defaultLightTheme;
5924
+ if (brandIdentity) {
5925
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5926
+ }
5927
+ if (lightOverrides) {
5928
+ theme2 = deepMerge2(theme2, lightOverrides);
5929
+ }
5930
+ return theme2;
5931
+ });
5932
+ const [darkTheme, setDarkTheme] = react.useState(() => {
5933
+ if (initialTheme && initialTheme.mode === "dark") return initialTheme;
5934
+ let theme2 = defaultDarkTheme;
5935
+ if (brandIdentity) {
5936
+ theme2 = createThemeFromBrand(brandIdentity, theme2);
5937
+ }
5938
+ if (darkOverrides) {
5939
+ theme2 = deepMerge2(theme2, darkOverrides);
5940
+ }
5941
+ return theme2;
5942
+ });
5943
+ const [isLoading, setIsLoading] = react.useState(!!themeUrl);
5944
+ const [error, setError] = react.useState(null);
5945
+ const resolvedMode = react.useMemo(() => resolveThemeMode(mode), [mode]);
5946
+ const theme = react.useMemo(
5947
+ () => resolvedMode === "dark" ? darkTheme : lightTheme,
5948
+ [resolvedMode, lightTheme, darkTheme]
5949
+ );
5950
+ const isDark = resolvedMode === "dark";
5951
+ const isLight = resolvedMode === "light";
5952
+ react.useEffect(() => {
5953
+ if (!themeUrl) return;
5954
+ setIsLoading(true);
5955
+ setError(null);
5956
+ loadThemeFromUrl(themeUrl).then((urlTheme) => {
5957
+ if (urlTheme) {
5958
+ setLightTheme((prev) => deepMerge2(prev, urlTheme));
5959
+ setDarkTheme((prev) => deepMerge2(prev, urlTheme));
5960
+ }
5961
+ }).catch((err) => {
5962
+ setError(err instanceof Error ? err.message : "Failed to load theme");
5963
+ }).finally(() => {
5964
+ setIsLoading(false);
5965
+ });
5966
+ }, [themeUrl]);
5967
+ react.useEffect(() => {
5968
+ if (typeof window !== "undefined") {
5969
+ injectCssVars(theme, cssVarPrefix);
5970
+ }
5971
+ }, [theme, cssVarPrefix]);
5972
+ react.useEffect(() => {
5973
+ if (typeof document !== "undefined") {
5974
+ document.documentElement.setAttribute("data-theme", resolvedMode);
5975
+ document.documentElement.style.colorScheme = resolvedMode;
5976
+ }
5977
+ }, [resolvedMode]);
5978
+ react.useEffect(() => {
5979
+ if (!enableSystemTheme || typeof window === "undefined") return;
5980
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
5981
+ const handleChange = () => {
5982
+ if (mode === "system") {
5983
+ setModeState("system");
5984
+ }
5985
+ };
5986
+ mediaQuery.addEventListener("change", handleChange);
5987
+ return () => mediaQuery.removeEventListener("change", handleChange);
5988
+ }, [mode, enableSystemTheme]);
5989
+ react.useEffect(() => {
5990
+ if (persistTheme && typeof window !== "undefined") {
5991
+ saveThemeMode(mode, storageKey);
5992
+ }
5993
+ }, [mode, persistTheme, storageKey]);
5994
+ const setMode = react.useCallback((newMode) => {
5995
+ setModeState(newMode);
5996
+ }, []);
5997
+ const toggleMode = react.useCallback(() => {
5998
+ setModeState((prev) => {
5999
+ const current = resolveThemeMode(prev);
6000
+ return current === "dark" ? "light" : "dark";
6001
+ });
6002
+ }, []);
6003
+ const updateTheme = react.useCallback((updates) => {
6004
+ setLightTheme((prev) => deepMerge2(prev, updates));
6005
+ setDarkTheme((prev) => deepMerge2(prev, updates));
6006
+ }, []);
6007
+ const resetTheme = react.useCallback(() => {
6008
+ let light = defaultLightTheme;
6009
+ let dark = defaultDarkTheme;
6010
+ if (brandIdentity) {
6011
+ light = createThemeFromBrand(brandIdentity, light);
6012
+ dark = createThemeFromBrand(brandIdentity, dark);
6013
+ }
6014
+ if (lightOverrides) {
6015
+ light = deepMerge2(light, lightOverrides);
6016
+ }
6017
+ if (darkOverrides) {
6018
+ dark = deepMerge2(dark, darkOverrides);
6019
+ }
6020
+ setLightTheme(light);
6021
+ setDarkTheme(dark);
6022
+ }, [brandIdentity, lightOverrides, darkOverrides]);
6023
+ const contextValue = react.useMemo(
6024
+ () => ({
6025
+ theme,
6026
+ mode,
6027
+ setMode,
6028
+ toggleMode,
6029
+ updateTheme,
6030
+ resetTheme,
6031
+ isDark,
6032
+ isLight,
6033
+ isLoading,
6034
+ error
6035
+ }),
6036
+ [theme, mode, setMode, toggleMode, updateTheme, resetTheme, isDark, isLight, isLoading, error]
6037
+ );
6038
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children });
6039
+ }
6040
+ function cssVar(path2, prefix = "--ec") {
6041
+ return `var(${prefix}-${path2.replace(/\./g, "-")})`;
6042
+ }
6043
+ function useThemeValue(selector) {
6044
+ const { theme } = useTheme();
6045
+ return selector(theme);
6046
+ }
6047
+ function ThemeToggle({
6048
+ className = "",
6049
+ size = 24,
6050
+ showLabel = false,
6051
+ lightLabel = "Light",
6052
+ darkLabel = "Dark"
6053
+ }) {
6054
+ const { isDark, toggleMode } = useTheme();
6055
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6056
+ "button",
6057
+ {
6058
+ type: "button",
6059
+ onClick: toggleMode,
6060
+ className: `ec-theme-toggle ${className}`,
6061
+ "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
6062
+ style: {
6063
+ background: "none",
6064
+ border: "none",
6065
+ cursor: "pointer",
6066
+ display: "inline-flex",
6067
+ alignItems: "center",
6068
+ gap: "0.5rem",
6069
+ padding: "0.5rem",
6070
+ borderRadius: "0.375rem",
6071
+ transition: "background-color 200ms ease-in-out"
6072
+ },
6073
+ children: [
6074
+ isDark ? (
6075
+ // Sun icon for dark mode (click to go light)
6076
+ /* @__PURE__ */ jsxRuntime.jsxs(
6077
+ "svg",
6078
+ {
6079
+ width: size,
6080
+ height: size,
6081
+ viewBox: "0 0 24 24",
6082
+ fill: "none",
6083
+ stroke: "currentColor",
6084
+ strokeWidth: "2",
6085
+ strokeLinecap: "round",
6086
+ strokeLinejoin: "round",
6087
+ children: [
6088
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }),
6089
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
6090
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
6091
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
6092
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
6093
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
6094
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
6095
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
6096
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
6097
+ ]
6098
+ }
6099
+ )
6100
+ ) : (
6101
+ // Moon icon for light mode (click to go dark)
6102
+ /* @__PURE__ */ jsxRuntime.jsx(
6103
+ "svg",
6104
+ {
6105
+ width: size,
6106
+ height: size,
6107
+ viewBox: "0 0 24 24",
6108
+ fill: "none",
6109
+ stroke: "currentColor",
6110
+ strokeWidth: "2",
6111
+ strokeLinecap: "round",
6112
+ strokeLinejoin: "round",
6113
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
6114
+ }
6115
+ )
6116
+ ),
6117
+ showLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isDark ? darkLabel : lightLabel })
6118
+ ]
6119
+ }
6120
+ );
6121
+ }
6122
+
6123
+ // src/client/web/astro/types.ts
6124
+ function dummyImage(width, height, text, bgColor = "cccccc", textColor = "969696") {
6125
+ const label = text ? `&text=${encodeURIComponent(text)}` : "";
6126
+ return `https://dummyimage.com/${width}x${height}/${bgColor}/${textColor}${label}`;
6127
+ }
6128
+ function loremIpsum(type = "paragraph", count = 1) {
6129
+ const words = [
6130
+ "lorem",
6131
+ "ipsum",
6132
+ "dolor",
6133
+ "sit",
6134
+ "amet",
6135
+ "consectetur",
6136
+ "adipiscing",
6137
+ "elit",
6138
+ "sed",
6139
+ "do",
6140
+ "eiusmod",
6141
+ "tempor",
6142
+ "incididunt",
6143
+ "ut",
6144
+ "labore",
6145
+ "et",
6146
+ "dolore",
6147
+ "magna",
6148
+ "aliqua",
6149
+ "enim",
6150
+ "ad",
6151
+ "minim",
6152
+ "veniam",
6153
+ "quis",
6154
+ "nostrud",
6155
+ "exercitation",
6156
+ "ullamco",
6157
+ "laboris",
6158
+ "nisi",
6159
+ "aliquip",
6160
+ "ex",
6161
+ "ea",
6162
+ "commodo",
6163
+ "consequat",
6164
+ "duis",
6165
+ "aute",
6166
+ "irure",
6167
+ "in",
6168
+ "reprehenderit",
6169
+ "voluptate",
6170
+ "velit",
6171
+ "esse",
6172
+ "cillum",
6173
+ "fugiat",
6174
+ "nulla",
6175
+ "pariatur",
6176
+ "excepteur",
6177
+ "sint",
6178
+ "occaecat",
6179
+ "cupidatat",
6180
+ "non",
6181
+ "proident",
6182
+ "sunt",
6183
+ "culpa",
6184
+ "qui",
6185
+ "officia",
6186
+ "deserunt",
6187
+ "mollit",
6188
+ "anim",
6189
+ "id",
6190
+ "est",
6191
+ "laborum"
6192
+ ];
6193
+ const getWords = (n) => {
6194
+ const result = [];
6195
+ for (let i = 0; i < n; i++) {
6196
+ result.push(words[Math.floor(Math.random() * words.length)]);
6197
+ }
6198
+ return result;
6199
+ };
6200
+ const capitalize2 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
6201
+ if (type === "word") {
6202
+ return getWords(count).join(" ");
6203
+ }
6204
+ if (type === "sentence") {
6205
+ const sentences = [];
6206
+ for (let i = 0; i < count; i++) {
6207
+ const sentence = capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".";
6208
+ sentences.push(sentence);
6209
+ }
6210
+ return sentences.join(" ");
6211
+ }
6212
+ const paragraphs = [];
6213
+ for (let i = 0; i < count; i++) {
6214
+ const sentences = [];
6215
+ const sentenceCount = Math.floor(Math.random() * 4) + 3;
6216
+ for (let j = 0; j < sentenceCount; j++) {
6217
+ sentences.push(capitalize2(getWords(Math.floor(Math.random() * 10) + 5).join(" ")) + ".");
6218
+ }
6219
+ paragraphs.push(sentences.join(" "));
6220
+ }
6221
+ return paragraphs.join("\n\n");
6222
+ }
6223
+ var dummyHeaderData = {
6224
+ logo: dummyImage(120, 40, "Logo"),
6225
+ logoAlt: "Company Logo",
6226
+ navLinks: [
6227
+ { text: "Home", href: "/", active: true },
6228
+ { text: "About", href: "/about" },
6229
+ { text: "Services", href: "/services" },
6230
+ { text: "Blog", href: "/blog" },
6231
+ { text: "Contact", href: "/contact" }
6232
+ ],
6233
+ cta: {
6234
+ text: "Get Started",
6235
+ href: "/signup",
6236
+ variant: "primary"
6237
+ },
6238
+ sticky: true
6239
+ };
6240
+ var dummyFooterData = {
6241
+ logo: dummyImage(120, 40, "Logo"),
6242
+ logoAlt: "Company Logo",
6243
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.",
6244
+ columns: [
6245
+ {
6246
+ title: "Product",
6247
+ links: [
6248
+ { text: "Features", href: "/features" },
6249
+ { text: "Pricing", href: "/pricing" },
6250
+ { text: "Integrations", href: "/integrations" },
6251
+ { text: "API", href: "/api" }
6252
+ ]
6253
+ },
6254
+ {
6255
+ title: "Company",
6256
+ links: [
6257
+ { text: "About", href: "/about" },
6258
+ { text: "Blog", href: "/blog" },
6259
+ { text: "Careers", href: "/careers" },
6260
+ { text: "Contact", href: "/contact" }
6261
+ ]
6262
+ },
6263
+ {
6264
+ title: "Legal",
6265
+ links: [
6266
+ { text: "Privacy Policy", href: "/privacy" },
6267
+ { text: "Terms of Service", href: "/terms" },
6268
+ { text: "Cookie Policy", href: "/cookies" }
6269
+ ]
6270
+ }
6271
+ ],
6272
+ socialLinks: [
6273
+ { platform: "twitter", href: "https://twitter.com" },
6274
+ { platform: "facebook", href: "https://facebook.com" },
6275
+ { platform: "instagram", href: "https://instagram.com" },
6276
+ { platform: "linkedin", href: "https://linkedin.com" },
6277
+ { platform: "github", href: "https://github.com" }
6278
+ ],
6279
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Company Name. All rights reserved.`
6280
+ };
6281
+ var dummyBannerData = {
6282
+ title: "Build Something Amazing Today",
6283
+ subtitle: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
6284
+ backgroundImage: dummyImage(1920, 800, "Hero+Background", "1e293b", "334155"),
6285
+ primaryCta: {
6286
+ text: "Get Started Free",
6287
+ href: "/signup",
6288
+ variant: "primary"
6289
+ },
6290
+ secondaryCta: {
6291
+ text: "Learn More",
6292
+ href: "/about",
6293
+ variant: "outline"
6294
+ },
6295
+ height: "lg",
6296
+ align: "center"
6297
+ };
6298
+ var dummyFeatures = [
6299
+ {
6300
+ title: "Lightning Fast",
6301
+ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
6302
+ 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>'
6303
+ },
6304
+ {
6305
+ title: "Secure & Reliable",
6306
+ description: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
6307
+ 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>'
6308
+ },
6309
+ {
6310
+ title: "Easy to Use",
6311
+ description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco.",
6312
+ 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>'
6313
+ }
6314
+ ];
6315
+ var dummyTestimonials = [
6316
+ {
6317
+ name: "John Doe",
6318
+ role: "CEO",
6319
+ company: "Tech Corp",
6320
+ avatar: dummyImage(80, 80, "JD", "3b82f6", "ffffff"),
6321
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
6322
+ rating: 5
6323
+ },
6324
+ {
6325
+ name: "Jane Smith",
6326
+ role: "CTO",
6327
+ company: "Startup Inc",
6328
+ avatar: dummyImage(80, 80, "JS", "10b981", "ffffff"),
6329
+ text: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
6330
+ rating: 5
6331
+ },
6332
+ {
6333
+ name: "Bob Wilson",
6334
+ role: "Product Manager",
6335
+ company: "Enterprise Co",
6336
+ avatar: dummyImage(80, 80, "BW", "f59e0b", "ffffff"),
6337
+ text: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
6338
+ rating: 4
6339
+ }
6340
+ ];
6341
+ var dummyPricingPlans = [
6342
+ {
6343
+ name: "Starter",
6344
+ description: "Perfect for individuals",
6345
+ price: "$9",
6346
+ period: "/month",
6347
+ features: [
6348
+ { text: "5 Projects", included: true },
6349
+ { text: "10GB Storage", included: true },
6350
+ { text: "Email Support", included: true },
6351
+ { text: "API Access", included: false },
6352
+ { text: "Custom Domain", included: false }
6353
+ ],
6354
+ ctaText: "Start Free Trial",
6355
+ ctaHref: "/signup?plan=starter"
6356
+ },
6357
+ {
6358
+ name: "Professional",
6359
+ description: "Best for growing teams",
6360
+ price: "$29",
6361
+ period: "/month",
6362
+ features: [
6363
+ { text: "Unlimited Projects", included: true },
6364
+ { text: "100GB Storage", included: true },
6365
+ { text: "Priority Support", included: true },
6366
+ { text: "API Access", included: true },
6367
+ { text: "Custom Domain", included: false }
6368
+ ],
6369
+ ctaText: "Start Free Trial",
6370
+ ctaHref: "/signup?plan=pro",
6371
+ popular: true,
6372
+ badge: "Most Popular"
6373
+ },
6374
+ {
6375
+ name: "Enterprise",
6376
+ description: "For large organizations",
6377
+ price: "$99",
6378
+ period: "/month",
6379
+ features: [
6380
+ { text: "Unlimited Projects", included: true },
6381
+ { text: "Unlimited Storage", included: true },
6382
+ { text: "24/7 Support", included: true },
6383
+ { text: "API Access", included: true },
6384
+ { text: "Custom Domain", included: true }
6385
+ ],
6386
+ ctaText: "Contact Sales",
6387
+ ctaHref: "/contact?plan=enterprise"
6388
+ }
6389
+ ];
6390
+ var dummyFaqItems = [
6391
+ {
6392
+ question: "What is your refund policy?",
6393
+ answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
6394
+ },
6395
+ {
6396
+ question: "How do I cancel my subscription?",
6397
+ answer: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
6398
+ },
6399
+ {
6400
+ question: "Can I change my plan later?",
6401
+ answer: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
6402
+ },
6403
+ {
6404
+ question: "Do you offer discounts for non-profits?",
6405
+ answer: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
6406
+ }
6407
+ ];
6408
+
6409
+ // src/client/web/forms/types.ts
6410
+ var VALIDATION_MESSAGES = {
6411
+ required: "This field is required",
6412
+ email: "Please enter a valid email address",
6413
+ phone: "Please enter a valid phone number",
6414
+ minLength: (min) => `Must be at least ${min} characters`,
6415
+ maxLength: (max) => `Must be no more than ${max} characters`,
6416
+ passwordMatch: "Passwords must match",
6417
+ acceptTerms: "You must accept the terms and conditions",
6418
+ passwordUppercase: "Password must contain at least one uppercase letter",
6419
+ passwordLowercase: "Password must contain at least one lowercase letter",
6420
+ passwordNumber: "Password must contain at least one number",
6421
+ passwordSpecial: "Password must contain at least one special character"
6422
+ };
6423
+ var contactFormSchema = Yup__namespace.object().shape({
6424
+ name: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(100, VALIDATION_MESSAGES.maxLength(100)),
6425
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
6426
+ phone: Yup__namespace.string().matches(
6427
+ /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
6428
+ VALIDATION_MESSAGES.phone
6429
+ ).nullable(),
6430
+ subject: Yup__namespace.string().max(200, VALIDATION_MESSAGES.maxLength(200)).nullable(),
6431
+ message: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(10, VALIDATION_MESSAGES.minLength(10)).max(2e3, VALIDATION_MESSAGES.maxLength(2e3))
6432
+ });
6433
+ var newsletterFormSchema = Yup__namespace.object().shape({
6434
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
6435
+ firstName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable(),
6436
+ lastName: Yup__namespace.string().min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)).nullable()
6437
+ });
6438
+ var loginFormSchema = Yup__namespace.object().shape({
6439
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
6440
+ password: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(8, VALIDATION_MESSAGES.minLength(8)),
6441
+ rememberMe: Yup__namespace.boolean()
6442
+ });
6443
+ function createRegisterFormSchema(requirements = {}) {
6444
+ const {
6445
+ minLength = 8,
6446
+ requireUppercase = true,
6447
+ requireLowercase = true,
6448
+ requireNumber = true,
6449
+ requireSpecial = false
6450
+ } = requirements;
6451
+ let passwordSchema = Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(minLength, VALIDATION_MESSAGES.minLength(minLength));
6452
+ if (requireUppercase) {
6453
+ passwordSchema = passwordSchema.matches(
6454
+ /[A-Z]/,
6455
+ VALIDATION_MESSAGES.passwordUppercase
6456
+ );
6457
+ }
6458
+ if (requireLowercase) {
6459
+ passwordSchema = passwordSchema.matches(
6460
+ /[a-z]/,
6461
+ VALIDATION_MESSAGES.passwordLowercase
6462
+ );
6463
+ }
6464
+ if (requireNumber) {
6465
+ passwordSchema = passwordSchema.matches(
6466
+ /[0-9]/,
6467
+ VALIDATION_MESSAGES.passwordNumber
6468
+ );
6469
+ }
6470
+ if (requireSpecial) {
6471
+ passwordSchema = passwordSchema.matches(
6472
+ /[!@#$%^&*(),.?":{}|<>]/,
6473
+ VALIDATION_MESSAGES.passwordSpecial
6474
+ );
6475
+ }
6476
+ return Yup__namespace.object().shape({
6477
+ firstName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
6478
+ lastName: Yup__namespace.string().required(VALIDATION_MESSAGES.required).min(2, VALIDATION_MESSAGES.minLength(2)).max(50, VALIDATION_MESSAGES.maxLength(50)),
6479
+ email: Yup__namespace.string().required(VALIDATION_MESSAGES.required).email(VALIDATION_MESSAGES.email),
6480
+ password: passwordSchema,
6481
+ confirmPassword: Yup__namespace.string().required(VALIDATION_MESSAGES.required).oneOf([Yup__namespace.ref("password")], VALIDATION_MESSAGES.passwordMatch),
6482
+ acceptTerms: Yup__namespace.boolean().oneOf([true], VALIDATION_MESSAGES.acceptTerms)
6483
+ });
6484
+ }
6485
+ var registerFormSchema = createRegisterFormSchema();
6486
+ var defaultInitialValues = {
6487
+ name: "",
6488
+ email: "",
6489
+ phone: "",
6490
+ subject: "",
6491
+ message: ""
6492
+ };
6493
+ var defaultSubjectOptions = [
6494
+ "General Inquiry",
6495
+ "Support Request",
6496
+ "Sales Question",
6497
+ "Partnership",
6498
+ "Feedback",
6499
+ "Other"
6500
+ ];
6501
+ function ContactForm({
6502
+ actionUrl,
6503
+ onSubmit,
6504
+ initialValues,
6505
+ showPhone = true,
6506
+ showSubject = true,
6507
+ subjectOptions = defaultSubjectOptions,
6508
+ submitText = "Send Message",
6509
+ successMessage = "Thank you! Your message has been sent successfully.",
6510
+ className = "",
6511
+ formClass = "",
6512
+ inputClass = "",
6513
+ labelClass = "",
6514
+ buttonClass = "",
6515
+ errorClass = ""
6516
+ }) {
6517
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6518
+ const [submitMessage, setSubmitMessage] = react.useState("");
6519
+ const mergedInitialValues = {
6520
+ ...defaultInitialValues,
6521
+ ...initialValues
6522
+ };
6523
+ 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";
6524
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6525
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6526
+ 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";
6527
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
6528
+ try {
6529
+ let result;
6530
+ if (onSubmit) {
6531
+ result = await onSubmit(values);
6532
+ } else if (actionUrl) {
6533
+ const response = await fetch(actionUrl, {
6534
+ method: "POST",
6535
+ headers: { "Content-Type": "application/json" },
6536
+ body: JSON.stringify(values)
6537
+ });
6538
+ result = await response.json();
6539
+ } else {
6540
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6541
+ result = { success: true };
6542
+ }
6543
+ if (result.success) {
6544
+ setSubmitStatus("success");
6545
+ setSubmitMessage(result.message || successMessage);
6546
+ resetForm();
6547
+ } else {
6548
+ setSubmitStatus("error");
6549
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
6550
+ }
6551
+ } catch (error) {
6552
+ setSubmitStatus("error");
6553
+ setSubmitMessage("An error occurred. Please try again later.");
6554
+ } finally {
6555
+ setSubmitting(false);
6556
+ }
6557
+ };
6558
+ 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: [
6559
+ /* @__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" }) }),
6560
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6561
+ /* @__PURE__ */ jsxRuntime.jsx(
6562
+ "button",
6563
+ {
6564
+ type: "button",
6565
+ onClick: () => setSubmitStatus("idle"),
6566
+ className: "mt-4 text-green-600 hover:text-green-700 text-sm font-medium",
6567
+ children: "Send another message"
6568
+ }
6569
+ )
6570
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
6571
+ formik.Formik,
6572
+ {
6573
+ initialValues: mergedInitialValues,
6574
+ validationSchema: contactFormSchema,
6575
+ onSubmit: handleSubmit,
6576
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6577
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6578
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-name", className: `${baseLabelClass} ${labelClass}`, children: [
6579
+ "Name ",
6580
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6581
+ ] }),
6582
+ /* @__PURE__ */ jsxRuntime.jsx(
6583
+ formik.Field,
6584
+ {
6585
+ type: "text",
6586
+ id: "contact-name",
6587
+ name: "name",
6588
+ placeholder: "John Doe",
6589
+ className: `${baseInputClass} ${inputClass} ${errors.name && touched.name ? "border-red-500 focus:ring-red-500" : ""}`
6590
+ }
6591
+ ),
6592
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "name", component: "p", className: `${baseErrorClass} ${errorClass}` })
6593
+ ] }),
6594
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6595
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-email", className: `${baseLabelClass} ${labelClass}`, children: [
6596
+ "Email ",
6597
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6598
+ ] }),
6599
+ /* @__PURE__ */ jsxRuntime.jsx(
6600
+ formik.Field,
6601
+ {
6602
+ type: "email",
6603
+ id: "contact-email",
6604
+ name: "email",
6605
+ placeholder: "john@example.com",
6606
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6607
+ }
6608
+ ),
6609
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: `${baseErrorClass} ${errorClass}` })
6610
+ ] }),
6611
+ showPhone && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6612
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-phone", className: `${baseLabelClass} ${labelClass}`, children: "Phone" }),
6613
+ /* @__PURE__ */ jsxRuntime.jsx(
6614
+ formik.Field,
6615
+ {
6616
+ type: "tel",
6617
+ id: "contact-phone",
6618
+ name: "phone",
6619
+ placeholder: "+1 (555) 000-0000",
6620
+ className: `${baseInputClass} ${inputClass} ${errors.phone && touched.phone ? "border-red-500 focus:ring-red-500" : ""}`
6621
+ }
6622
+ ),
6623
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "phone", component: "p", className: `${baseErrorClass} ${errorClass}` })
6624
+ ] }),
6625
+ showSubject && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6626
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "contact-subject", className: `${baseLabelClass} ${labelClass}`, children: "Subject" }),
6627
+ /* @__PURE__ */ jsxRuntime.jsxs(
6628
+ formik.Field,
6629
+ {
6630
+ as: "select",
6631
+ id: "contact-subject",
6632
+ name: "subject",
6633
+ className: `${baseInputClass} ${inputClass}`,
6634
+ children: [
6635
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select a subject..." }),
6636
+ subjectOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: option }, option))
6637
+ ]
6638
+ }
6639
+ ),
6640
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "subject", component: "p", className: `${baseErrorClass} ${errorClass}` })
6641
+ ] }),
6642
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6643
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "contact-message", className: `${baseLabelClass} ${labelClass}`, children: [
6644
+ "Message ",
6645
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
6646
+ ] }),
6647
+ /* @__PURE__ */ jsxRuntime.jsx(
6648
+ formik.Field,
6649
+ {
6650
+ as: "textarea",
6651
+ id: "contact-message",
6652
+ name: "message",
6653
+ rows: 5,
6654
+ placeholder: "Your message...",
6655
+ className: `${baseInputClass} ${inputClass} resize-none ${errors.message && touched.message ? "border-red-500 focus:ring-red-500" : ""}`
6656
+ }
6657
+ ),
6658
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "message", component: "p", className: `${baseErrorClass} ${errorClass}` })
6659
+ ] }),
6660
+ 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 }) }),
6661
+ /* @__PURE__ */ jsxRuntime.jsx(
6662
+ "button",
6663
+ {
6664
+ type: "submit",
6665
+ disabled: isSubmitting,
6666
+ className: `${baseButtonClass} ${buttonClass}`,
6667
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6668
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6669
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6670
+ /* @__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" })
6671
+ ] }),
6672
+ "Sending..."
6673
+ ] }) : submitText
6674
+ }
6675
+ )
6676
+ ] })
6677
+ }
6678
+ ) });
6679
+ }
6680
+ var defaultInitialValues2 = {
6681
+ email: "",
6682
+ firstName: "",
6683
+ lastName: ""
6684
+ };
6685
+ function NewsletterForm({
6686
+ actionUrl,
6687
+ onSubmit,
6688
+ initialValues,
6689
+ showName = false,
6690
+ placeholder = "Enter your email",
6691
+ submitText = "Subscribe",
6692
+ successMessage = "Thank you for subscribing!",
6693
+ layout = "inline",
6694
+ className = "",
6695
+ formClass = "",
6696
+ inputClass = "",
6697
+ buttonClass = ""
6698
+ }) {
6699
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6700
+ const [submitMessage, setSubmitMessage] = react.useState("");
6701
+ const mergedInitialValues = {
6702
+ ...defaultInitialValues2,
6703
+ ...initialValues
6704
+ };
6705
+ 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";
6706
+ 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";
6707
+ const handleSubmit = async (values, { setSubmitting, resetForm }) => {
6708
+ try {
6709
+ let result;
6710
+ if (onSubmit) {
6711
+ result = await onSubmit(values);
6712
+ } else if (actionUrl) {
6713
+ const response = await fetch(actionUrl, {
6714
+ method: "POST",
6715
+ headers: { "Content-Type": "application/json" },
6716
+ body: JSON.stringify(values)
6717
+ });
6718
+ result = await response.json();
6719
+ } else {
6720
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6721
+ result = { success: true };
6722
+ }
6723
+ if (result.success) {
6724
+ setSubmitStatus("success");
6725
+ setSubmitMessage(result.message || successMessage);
6726
+ resetForm();
6727
+ } else {
6728
+ setSubmitStatus("error");
6729
+ setSubmitMessage(result.message || "Something went wrong. Please try again.");
6730
+ }
6731
+ } catch (error) {
6732
+ setSubmitStatus("error");
6733
+ setSubmitMessage("An error occurred. Please try again later.");
6734
+ } finally {
6735
+ setSubmitting(false);
6736
+ }
6737
+ };
6738
+ if (submitStatus === "success") {
6739
+ 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: [
6740
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
6741
+ /* @__PURE__ */ jsxRuntime.jsx(
6742
+ "button",
6743
+ {
6744
+ type: "button",
6745
+ onClick: () => setSubmitStatus("idle"),
6746
+ className: "mt-2 text-green-600 hover:text-green-700 text-sm",
6747
+ children: "Subscribe another email"
6748
+ }
6749
+ )
6750
+ ] }) });
6751
+ }
6752
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `ec-newsletter-form ${className}`, children: [
6753
+ /* @__PURE__ */ jsxRuntime.jsx(
6754
+ formik.Formik,
6755
+ {
6756
+ initialValues: mergedInitialValues,
6757
+ validationSchema: newsletterFormSchema,
6758
+ onSubmit: handleSubmit,
6759
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(
6760
+ formik.Form,
6761
+ {
6762
+ className: `${layout === "inline" ? "flex flex-col sm:flex-row gap-3" : "space-y-4"} ${formClass}`,
6763
+ noValidate: true,
6764
+ children: [
6765
+ showName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex gap-3 flex-1" : "grid grid-cols-2 gap-4", children: [
6766
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
6767
+ /* @__PURE__ */ jsxRuntime.jsx(
6768
+ formik.Field,
6769
+ {
6770
+ type: "text",
6771
+ name: "firstName",
6772
+ placeholder: "First name",
6773
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500" : ""}`
6774
+ }
6775
+ ),
6776
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: "text-sm text-red-600 mt-1" })
6777
+ ] }),
6778
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
6779
+ /* @__PURE__ */ jsxRuntime.jsx(
6780
+ formik.Field,
6781
+ {
6782
+ type: "text",
6783
+ name: "lastName",
6784
+ placeholder: "Last name",
6785
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500" : ""}`
6786
+ }
6787
+ ),
6788
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: "text-sm text-red-600 mt-1" })
6789
+ ] })
6790
+ ] }),
6791
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: layout === "inline" ? "flex-1" : "", children: [
6792
+ /* @__PURE__ */ jsxRuntime.jsx(
6793
+ formik.Field,
6794
+ {
6795
+ type: "email",
6796
+ name: "email",
6797
+ placeholder,
6798
+ className: `w-full ${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500" : ""}`
6799
+ }
6800
+ ),
6801
+ layout === "stacked" && /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: "text-sm text-red-600 mt-1" })
6802
+ ] }),
6803
+ /* @__PURE__ */ jsxRuntime.jsx(
6804
+ "button",
6805
+ {
6806
+ type: "submit",
6807
+ disabled: isSubmitting,
6808
+ className: `${baseButtonClass} ${buttonClass} ${layout === "stacked" ? "w-full" : ""}`,
6809
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6810
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6811
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6812
+ /* @__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" })
6813
+ ] }),
6814
+ "Subscribing..."
6815
+ ] }) : submitText
6816
+ }
6817
+ ),
6818
+ 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 }) })
6819
+ ]
6820
+ }
6821
+ )
6822
+ }
6823
+ ),
6824
+ 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 }) })
6825
+ ] });
6826
+ }
6827
+ var defaultInitialValues3 = {
6828
+ email: "",
6829
+ password: "",
6830
+ rememberMe: false
6831
+ };
6832
+ function LoginForm({
6833
+ actionUrl,
6834
+ onSubmit,
6835
+ initialValues,
6836
+ showRememberMe = true,
6837
+ forgotPasswordLink = "/forgot-password",
6838
+ registerLink = "/register",
6839
+ submitText = "Sign In",
6840
+ successRedirect,
6841
+ className = "",
6842
+ formClass = "",
6843
+ inputClass = "",
6844
+ buttonClass = ""
6845
+ }) {
6846
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
6847
+ const [submitMessage, setSubmitMessage] = react.useState("");
6848
+ const [showPassword, setShowPassword] = react.useState(false);
6849
+ const mergedInitialValues = {
6850
+ ...defaultInitialValues3,
6851
+ ...initialValues
6852
+ };
6853
+ 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";
6854
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
6855
+ const baseErrorClass = "text-sm text-red-600 mt-1";
6856
+ 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";
6857
+ const handleSubmit = async (values, { setSubmitting }) => {
6858
+ try {
6859
+ let result;
6860
+ if (onSubmit) {
6861
+ result = await onSubmit(values);
6862
+ } else if (actionUrl) {
6863
+ const response = await fetch(actionUrl, {
6864
+ method: "POST",
6865
+ headers: { "Content-Type": "application/json" },
6866
+ body: JSON.stringify(values)
6867
+ });
6868
+ result = await response.json();
6869
+ } else {
6870
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
6871
+ result = { success: true };
6872
+ }
6873
+ if (result.success) {
6874
+ setSubmitStatus("success");
6875
+ setSubmitMessage(result.message || "Login successful!");
6876
+ if (successRedirect && typeof window !== "undefined") {
6877
+ window.location.href = successRedirect;
6878
+ }
6879
+ } else {
6880
+ setSubmitStatus("error");
6881
+ setSubmitMessage(result.message || "Invalid email or password.");
6882
+ }
6883
+ } catch (error) {
6884
+ setSubmitStatus("error");
6885
+ setSubmitMessage("An error occurred. Please try again later.");
6886
+ } finally {
6887
+ setSubmitting(false);
6888
+ }
6889
+ };
6890
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-login-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
6891
+ formik.Formik,
6892
+ {
6893
+ initialValues: mergedInitialValues,
6894
+ validationSchema: loginFormSchema,
6895
+ onSubmit: handleSubmit,
6896
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
6897
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6898
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-email", className: baseLabelClass, children: "Email" }),
6899
+ /* @__PURE__ */ jsxRuntime.jsx(
6900
+ formik.Field,
6901
+ {
6902
+ type: "email",
6903
+ id: "login-email",
6904
+ name: "email",
6905
+ placeholder: "you@example.com",
6906
+ autoComplete: "email",
6907
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
6908
+ }
6909
+ ),
6910
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
6911
+ ] }),
6912
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6913
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "login-password", className: baseLabelClass, children: "Password" }),
6914
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6915
+ /* @__PURE__ */ jsxRuntime.jsx(
6916
+ formik.Field,
6917
+ {
6918
+ type: showPassword ? "text" : "password",
6919
+ id: "login-password",
6920
+ name: "password",
6921
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
6922
+ autoComplete: "current-password",
6923
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
6924
+ }
6925
+ ),
6926
+ /* @__PURE__ */ jsxRuntime.jsx(
6927
+ "button",
6928
+ {
6929
+ type: "button",
6930
+ onClick: () => setShowPassword(!showPassword),
6931
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
6932
+ tabIndex: -1,
6933
+ 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: [
6934
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
6935
+ /* @__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" })
6936
+ ] })
6937
+ }
6938
+ )
6939
+ ] }),
6940
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass })
6941
+ ] }),
6942
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
6943
+ showRememberMe && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
6944
+ /* @__PURE__ */ jsxRuntime.jsx(
6945
+ formik.Field,
6946
+ {
6947
+ type: "checkbox",
6948
+ name: "rememberMe",
6949
+ className: "w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
6950
+ }
6951
+ ),
6952
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-600", children: "Remember me" })
6953
+ ] }),
6954
+ forgotPasswordLink && /* @__PURE__ */ jsxRuntime.jsx(
6955
+ "a",
6956
+ {
6957
+ href: forgotPasswordLink,
6958
+ className: "text-sm text-blue-600 hover:text-blue-700 font-medium",
6959
+ children: "Forgot password?"
6960
+ }
6961
+ )
6962
+ ] }),
6963
+ 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 }) }),
6964
+ /* @__PURE__ */ jsxRuntime.jsx(
6965
+ "button",
6966
+ {
6967
+ type: "submit",
6968
+ disabled: isSubmitting,
6969
+ className: `${baseButtonClass} ${buttonClass}`,
6970
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
6971
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
6972
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6973
+ /* @__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" })
6974
+ ] }),
6975
+ "Signing in..."
6976
+ ] }) : submitText
6977
+ }
6978
+ ),
6979
+ registerLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
6980
+ "Don't have an account?",
6981
+ " ",
6982
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: registerLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign up" })
6983
+ ] })
6984
+ ] })
6985
+ }
6986
+ ) });
6987
+ }
6988
+ var defaultInitialValues4 = {
6989
+ firstName: "",
6990
+ lastName: "",
6991
+ email: "",
6992
+ password: "",
6993
+ confirmPassword: "",
6994
+ acceptTerms: false
6995
+ };
6996
+ function RegisterForm({
6997
+ actionUrl,
6998
+ onSubmit,
6999
+ initialValues,
7000
+ termsLink = "/terms",
7001
+ privacyLink = "/privacy",
7002
+ loginLink = "/login",
7003
+ submitText = "Create Account",
7004
+ successRedirect,
7005
+ passwordRequirements = {
7006
+ minLength: 8,
7007
+ requireUppercase: true,
7008
+ requireLowercase: true,
7009
+ requireNumber: true,
7010
+ requireSpecial: false
7011
+ },
7012
+ className = "",
7013
+ formClass = "",
7014
+ inputClass = "",
7015
+ buttonClass = ""
7016
+ }) {
7017
+ const [submitStatus, setSubmitStatus] = react.useState("idle");
7018
+ const [submitMessage, setSubmitMessage] = react.useState("");
7019
+ const [showPassword, setShowPassword] = react.useState(false);
7020
+ const [showConfirmPassword, setShowConfirmPassword] = react.useState(false);
7021
+ const mergedInitialValues = {
7022
+ ...defaultInitialValues4,
7023
+ ...initialValues
7024
+ };
7025
+ const validationSchema = createRegisterFormSchema(passwordRequirements);
7026
+ 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";
7027
+ const baseLabelClass = "block text-sm font-medium text-gray-700 mb-1";
7028
+ const baseErrorClass = "text-sm text-red-600 mt-1";
7029
+ 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";
7030
+ const handleSubmit = async (values, { setSubmitting }) => {
7031
+ try {
7032
+ let result;
7033
+ if (onSubmit) {
7034
+ result = await onSubmit(values);
7035
+ } else if (actionUrl) {
7036
+ const response = await fetch(actionUrl, {
7037
+ method: "POST",
7038
+ headers: { "Content-Type": "application/json" },
7039
+ body: JSON.stringify(values)
7040
+ });
7041
+ result = await response.json();
7042
+ } else {
7043
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
7044
+ result = { success: true };
7045
+ }
7046
+ if (result.success) {
7047
+ setSubmitStatus("success");
7048
+ setSubmitMessage(result.message || "Account created successfully!");
7049
+ if (successRedirect && typeof window !== "undefined") {
7050
+ window.location.href = successRedirect;
7051
+ }
7052
+ } else {
7053
+ setSubmitStatus("error");
7054
+ setSubmitMessage(result.message || "Registration failed. Please try again.");
7055
+ }
7056
+ } catch (error) {
7057
+ setSubmitStatus("error");
7058
+ setSubmitMessage("An error occurred. Please try again later.");
7059
+ } finally {
7060
+ setSubmitting(false);
7061
+ }
7062
+ };
7063
+ if (submitStatus === "success") {
7064
+ 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: [
7065
+ /* @__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" }) }),
7066
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-green-800 font-medium", children: submitMessage }),
7067
+ loginLink && /* @__PURE__ */ jsxRuntime.jsx(
7068
+ "a",
7069
+ {
7070
+ href: loginLink,
7071
+ className: "inline-block mt-4 text-green-600 hover:text-green-700 font-medium",
7072
+ children: "Sign in to your account"
7073
+ }
7074
+ )
7075
+ ] }) });
7076
+ }
7077
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ec-register-form ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
7078
+ formik.Formik,
7079
+ {
7080
+ initialValues: mergedInitialValues,
7081
+ validationSchema,
7082
+ onSubmit: handleSubmit,
7083
+ children: ({ isSubmitting, errors, touched }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: `space-y-4 ${formClass}`, noValidate: true, children: [
7084
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [
7085
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7086
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-firstName", className: baseLabelClass, children: [
7087
+ "First Name ",
7088
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
7089
+ ] }),
7090
+ /* @__PURE__ */ jsxRuntime.jsx(
7091
+ formik.Field,
7092
+ {
7093
+ type: "text",
7094
+ id: "register-firstName",
7095
+ name: "firstName",
7096
+ placeholder: "John",
7097
+ autoComplete: "given-name",
7098
+ className: `${baseInputClass} ${inputClass} ${errors.firstName && touched.firstName ? "border-red-500 focus:ring-red-500" : ""}`
7099
+ }
7100
+ ),
7101
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "firstName", component: "p", className: baseErrorClass })
7102
+ ] }),
7103
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7104
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-lastName", className: baseLabelClass, children: [
7105
+ "Last Name ",
7106
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
7107
+ ] }),
7108
+ /* @__PURE__ */ jsxRuntime.jsx(
7109
+ formik.Field,
7110
+ {
7111
+ type: "text",
7112
+ id: "register-lastName",
7113
+ name: "lastName",
7114
+ placeholder: "Doe",
7115
+ autoComplete: "family-name",
7116
+ className: `${baseInputClass} ${inputClass} ${errors.lastName && touched.lastName ? "border-red-500 focus:ring-red-500" : ""}`
7117
+ }
7118
+ ),
7119
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "lastName", component: "p", className: baseErrorClass })
7120
+ ] })
7121
+ ] }),
7122
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7123
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-email", className: baseLabelClass, children: [
7124
+ "Email ",
7125
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
7126
+ ] }),
7127
+ /* @__PURE__ */ jsxRuntime.jsx(
7128
+ formik.Field,
7129
+ {
7130
+ type: "email",
7131
+ id: "register-email",
7132
+ name: "email",
7133
+ placeholder: "you@example.com",
7134
+ autoComplete: "email",
7135
+ className: `${baseInputClass} ${inputClass} ${errors.email && touched.email ? "border-red-500 focus:ring-red-500" : ""}`
7136
+ }
7137
+ ),
7138
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "email", component: "p", className: baseErrorClass })
7139
+ ] }),
7140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7141
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-password", className: baseLabelClass, children: [
7142
+ "Password ",
7143
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
7144
+ ] }),
7145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
7146
+ /* @__PURE__ */ jsxRuntime.jsx(
7147
+ formik.Field,
7148
+ {
7149
+ type: showPassword ? "text" : "password",
7150
+ id: "register-password",
7151
+ name: "password",
7152
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
7153
+ autoComplete: "new-password",
7154
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.password && touched.password ? "border-red-500 focus:ring-red-500" : ""}`
7155
+ }
7156
+ ),
7157
+ /* @__PURE__ */ jsxRuntime.jsx(
7158
+ "button",
7159
+ {
7160
+ type: "button",
7161
+ onClick: () => setShowPassword(!showPassword),
7162
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
7163
+ tabIndex: -1,
7164
+ 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: [
7165
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
7166
+ /* @__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" })
7167
+ ] })
7168
+ }
7169
+ )
7170
+ ] }),
7171
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "password", component: "p", className: baseErrorClass }),
7172
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
7173
+ "Min ",
7174
+ passwordRequirements.minLength,
7175
+ " characters",
7176
+ passwordRequirements.requireUppercase && ", uppercase",
7177
+ passwordRequirements.requireLowercase && ", lowercase",
7178
+ passwordRequirements.requireNumber && ", number",
7179
+ passwordRequirements.requireSpecial && ", special character"
7180
+ ] })
7181
+ ] }),
7182
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7183
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "register-confirmPassword", className: baseLabelClass, children: [
7184
+ "Confirm Password ",
7185
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
7186
+ ] }),
7187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
7188
+ /* @__PURE__ */ jsxRuntime.jsx(
7189
+ formik.Field,
7190
+ {
7191
+ type: showConfirmPassword ? "text" : "password",
7192
+ id: "register-confirmPassword",
7193
+ name: "confirmPassword",
7194
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
7195
+ autoComplete: "new-password",
7196
+ className: `${baseInputClass} ${inputClass} pr-12 ${errors.confirmPassword && touched.confirmPassword ? "border-red-500 focus:ring-red-500" : ""}`
7197
+ }
7198
+ ),
7199
+ /* @__PURE__ */ jsxRuntime.jsx(
7200
+ "button",
7201
+ {
7202
+ type: "button",
7203
+ onClick: () => setShowConfirmPassword(!showConfirmPassword),
7204
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700",
7205
+ tabIndex: -1,
7206
+ 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: [
7207
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }),
7208
+ /* @__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" })
7209
+ ] })
7210
+ }
7211
+ )
7212
+ ] }),
7213
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "confirmPassword", component: "p", className: baseErrorClass })
7214
+ ] }),
7215
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7216
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
7217
+ /* @__PURE__ */ jsxRuntime.jsx(
7218
+ formik.Field,
7219
+ {
7220
+ type: "checkbox",
7221
+ name: "acceptTerms",
7222
+ className: "w-4 h-4 mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
7223
+ }
7224
+ ),
7225
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600", children: [
7226
+ "I agree to the",
7227
+ " ",
7228
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: termsLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }),
7229
+ " ",
7230
+ "and",
7231
+ " ",
7232
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: privacyLink, className: "text-blue-600 hover:underline", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }),
7233
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: " *" })
7234
+ ] })
7235
+ ] }),
7236
+ /* @__PURE__ */ jsxRuntime.jsx(formik.ErrorMessage, { name: "acceptTerms", component: "p", className: baseErrorClass })
7237
+ ] }),
7238
+ 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 }) }),
7239
+ /* @__PURE__ */ jsxRuntime.jsx(
7240
+ "button",
7241
+ {
7242
+ type: "submit",
7243
+ disabled: isSubmitting,
7244
+ className: `${baseButtonClass} ${buttonClass}`,
7245
+ children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
7246
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin w-5 h-5", fill: "none", viewBox: "0 0 24 24", children: [
7247
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
7248
+ /* @__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" })
7249
+ ] }),
7250
+ "Creating account..."
7251
+ ] }) : submitText
7252
+ }
7253
+ ),
7254
+ loginLink && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm text-gray-600", children: [
7255
+ "Already have an account?",
7256
+ " ",
7257
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: loginLink, className: "text-blue-600 hover:text-blue-700 font-medium", children: "Sign in" })
7258
+ ] })
7259
+ ] })
7260
+ }
7261
+ ) });
7262
+ }
7263
+
7264
+ // src/shared/index.ts
7265
+ var shared_exports = {};
7266
+ __export(shared_exports, {
7267
+ BREAKPOINTS: () => BREAKPOINTS,
7268
+ CONTAINER_WIDTHS: () => CONTAINER_WIDTHS,
7269
+ DATE_FORMAT: () => DATE_FORMAT,
7270
+ DATE_FORMATS: () => DATE_FORMATS,
7271
+ ENUMS: () => ENUMS,
7272
+ ENUMS_DEFAULT: () => enums_default,
7273
+ FILE_TYPE: () => FILE_TYPE,
7274
+ GENDER: () => GENDER,
7275
+ HTTP_STATUS: () => HTTP_STATUS,
7276
+ HTTP_STATUS_MESSAGES: () => HTTP_STATUS_MESSAGES,
7277
+ INTERVAL: () => INTERVAL,
7278
+ LOCALE: () => LOCALE,
7279
+ MEDIA_QUERIES: () => MEDIA_QUERIES,
7280
+ MEDIA_QUERIES_MAX: () => MEDIA_QUERIES_MAX,
7281
+ NOTIFICATION_TYPE: () => NOTIFICATION_TYPE,
7282
+ ORDER_STATUS: () => ORDER_STATUS,
7283
+ PAGINATION: () => PAGINATION,
7284
+ PAYMENT_STATUS: () => PAYMENT_STATUS,
7285
+ PERMISSION_LEVEL: () => PERMISSION_LEVEL,
7286
+ PRIORITY: () => PRIORITY,
7287
+ ROLE: () => ROLE,
7288
+ ROLES: () => ROLES,
7289
+ SORT: () => SORT,
7290
+ SORT_DIRECTION: () => SORT_DIRECTION,
7291
+ STATUS: () => STATUS,
7292
+ SUBSCRIPTION_STATUS: () => SUBSCRIPTION_STATUS,
7293
+ TASK_STATUS: () => TASK_STATUS,
7294
+ THEME: () => THEME,
7295
+ TOKEN_TYPES: () => TOKEN_TYPES,
7296
+ USER_STATUS: () => USER_STATUS,
7297
+ VALIDATION_MESSAGES: () => VALIDATION_MESSAGES2,
7298
+ VALIDATION_PATTERNS: () => VALIDATION_PATTERNS,
7299
+ VALIDATION_RULES: () => VALIDATION_RULES,
7300
+ VISIBILITY: () => VISIBILITY,
7301
+ addDays: () => dateFns.addDays,
7302
+ addHours: () => dateFns.addHours,
7303
+ addMinutes: () => dateFns.addMinutes,
7304
+ addMonths: () => dateFns.addMonths,
7305
+ addTime: () => addTime,
7306
+ addWeeks: () => dateFns.addWeeks,
7307
+ addYears: () => dateFns.addYears,
7308
+ combineDateAndTime: () => combineDateAndTime,
7309
+ dateTime: () => date_time_default,
7310
+ daysSince: () => daysSince,
7311
+ daysUntil: () => daysUntil,
7312
+ differenceInDays: () => dateFns.differenceInDays,
7313
+ differenceInHours: () => dateFns.differenceInHours,
7314
+ differenceInMinutes: () => dateFns.differenceInMinutes,
7315
+ differenceInMonths: () => dateFns.differenceInMonths,
7316
+ differenceInSeconds: () => dateFns.differenceInSeconds,
7317
+ differenceInWeeks: () => dateFns.differenceInWeeks,
7318
+ differenceInYears: () => dateFns.differenceInYears,
7319
+ doDateRangesOverlap: () => doDateRangesOverlap,
7320
+ eachDayOfInterval: () => dateFns.eachDayOfInterval,
7321
+ eachMonthOfInterval: () => dateFns.eachMonthOfInterval,
7322
+ eachWeekOfInterval: () => dateFns.eachWeekOfInterval,
7323
+ endOfDay: () => dateFns.endOfDay,
7324
+ endOfMonth: () => dateFns.endOfMonth,
7325
+ endOfWeek: () => dateFns.endOfWeek,
7326
+ endOfYear: () => dateFns.endOfYear,
7327
+ format: () => dateFns.format,
7328
+ formatDate: () => formatDate2,
7329
+ formatDateInTimezone: () => formatDateInTimezone,
7330
+ formatDateRange: () => formatDateRange,
7331
+ formatDateTime: () => formatDateTime2,
7332
+ formatDistance: () => dateFns.formatDistance,
3960
7333
  formatDistanceToNow: () => dateFns.formatDistanceToNow,
3961
7334
  formatDuration: () => dateFns.formatDuration,
3962
7335
  formatInTimeZone: () => dateFnsTz.formatInTimeZone,
@@ -3997,7 +7370,7 @@ __export(shared_exports, {
3997
7370
  isSameMonth: () => dateFns.isSameMonth,
3998
7371
  isSameWeek: () => dateFns.isSameWeek,
3999
7372
  isSameYear: () => dateFns.isSameYear,
4000
- isTest: () => isTest,
7373
+ isTest: () => isTest2,
4001
7374
  isThisMonth: () => dateFns.isThisMonth,
4002
7375
  isThisWeek: () => dateFns.isThisWeek,
4003
7376
  isThisYear: () => dateFns.isThisYear,
@@ -4076,7 +7449,7 @@ var isProd = () => {
4076
7449
  var isDev = () => {
4077
7450
  return process.env.NODE_ENV === "development";
4078
7451
  };
4079
- var isTest = () => {
7452
+ var isTest2 = () => {
4080
7453
  return process.env.NODE_ENV === "test";
4081
7454
  };
4082
7455
  var validateEnv = (requiredVars) => {
@@ -4844,7 +8217,7 @@ var isValidUsername = (username) => {
4844
8217
  var isValidSlug = (slug) => {
4845
8218
  return VALIDATION_PATTERNS.SLUG.test(slug);
4846
8219
  };
4847
- var VALIDATION_MESSAGES = {
8220
+ var VALIDATION_MESSAGES2 = {
4848
8221
  // Required fields
4849
8222
  REQUIRED: "This field is required",
4850
8223
  REQUIRED_FIELD: (field) => `${field} is required`,
@@ -4885,17 +8258,17 @@ var VALIDATION_MESSAGES = {
4885
8258
  var VALIDATION_RULES = {
4886
8259
  email: {
4887
8260
  pattern: VALIDATION_PATTERNS.EMAIL,
4888
- message: VALIDATION_MESSAGES.EMAIL_INVALID
8261
+ message: VALIDATION_MESSAGES2.EMAIL_INVALID
4889
8262
  },
4890
8263
  password: {
4891
8264
  minLength: 8,
4892
8265
  pattern: VALIDATION_PATTERNS.PASSWORD_MEDIUM,
4893
- message: VALIDATION_MESSAGES.PASSWORD_MEDIUM
8266
+ message: VALIDATION_MESSAGES2.PASSWORD_MEDIUM
4894
8267
  },
4895
8268
  passwordStrong: {
4896
8269
  minLength: 8,
4897
8270
  pattern: VALIDATION_PATTERNS.PASSWORD_STRONG,
4898
- message: VALIDATION_MESSAGES.PASSWORD_STRONG
8271
+ message: VALIDATION_MESSAGES2.PASSWORD_STRONG
4899
8272
  },
4900
8273
  name: {
4901
8274
  minLength: 2,
@@ -4905,15 +8278,15 @@ var VALIDATION_RULES = {
4905
8278
  minLength: 3,
4906
8279
  maxLength: 30,
4907
8280
  pattern: VALIDATION_PATTERNS.USERNAME,
4908
- message: VALIDATION_MESSAGES.USERNAME_INVALID
8281
+ message: VALIDATION_MESSAGES2.USERNAME_INVALID
4909
8282
  },
4910
8283
  phone: {
4911
8284
  pattern: VALIDATION_PATTERNS.PHONE_INTERNATIONAL,
4912
- message: VALIDATION_MESSAGES.PHONE_INVALID
8285
+ message: VALIDATION_MESSAGES2.PHONE_INVALID
4913
8286
  },
4914
8287
  url: {
4915
8288
  pattern: VALIDATION_PATTERNS.URL,
4916
- message: VALIDATION_MESSAGES.URL_INVALID
8289
+ message: VALIDATION_MESSAGES2.URL_INVALID
4917
8290
  }
4918
8291
  };
4919
8292