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