@mohasinac/appkit 4.41.16 → 4.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +1 -1
  2. package/dist/_internal/server/features/checkout/actions.d.ts +16 -14
  3. package/dist/_internal/server/features/checkout/actions.js +145 -97
  4. package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +1 -1
  5. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  6. package/dist/_internal/server/features/checkout/index.js +1 -1
  7. package/dist/_internal/server/features/checkout/locked-lines.js +1 -1
  8. package/dist/_internal/server/features/checkout/source-context.js +2 -2
  9. package/dist/_internal/server/features/maintenance/analyze.js +1 -1
  10. package/dist/_internal/server/features/refunds/actions.d.ts +4 -4
  11. package/dist/_internal/server/features/refunds/actions.js +9 -8
  12. package/dist/_internal/server/functions/scheduled.d.ts +1 -2
  13. package/dist/_internal/server/functions/scheduled.js +1 -9
  14. package/dist/_internal/server/jobs/core/index.d.ts +0 -1
  15. package/dist/_internal/server/jobs/core/index.js +0 -1
  16. package/dist/_internal/server/jobs/handlers/index.d.ts +0 -1
  17. package/dist/_internal/server/jobs/handlers/index.js +0 -1
  18. package/dist/_internal/shared/actions/action-registry.js +2 -2
  19. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  20. package/dist/_internal/shared/checkout/order-math.js +1 -1
  21. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +2 -2
  22. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  23. package/dist/_internal/shared/features/cart/schema.d.ts +6 -6
  24. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  25. package/dist/_internal/shared/features/orders/refund-copy.js +1 -1
  26. package/dist/_internal/shared/features/orders/schema.d.ts +5 -5
  27. package/dist/_internal/shared/features/orders/schema.js +1 -1
  28. package/dist/_internal/shared/features/products/schema.d.ts +2 -2
  29. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  30. package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
  31. package/dist/client.d.ts +1 -1
  32. package/dist/client.js +1 -1
  33. package/dist/configs/next.js +2 -2
  34. package/dist/constants/field-names.d.ts +1 -1
  35. package/dist/constants/field-names.js +1 -1
  36. package/dist/contracts/index.d.ts +0 -2
  37. package/dist/contracts/index.js +0 -1
  38. package/dist/contracts/payment.d.ts +13 -2
  39. package/dist/contracts/payment.js +2 -2
  40. package/dist/core/integration-keys.d.ts +7 -3
  41. package/dist/core/integration-keys.js +13 -7
  42. package/dist/core/money.d.ts +11 -0
  43. package/dist/core/money.js +15 -0
  44. package/dist/errors/index.d.ts +1 -1
  45. package/dist/errors/index.js +1 -1
  46. package/dist/errors/messages.d.ts +1 -0
  47. package/dist/errors/messages.js +1 -0
  48. package/dist/errors/{razorpay-unreachable.d.ts → payment-provider-unreachable.d.ts} +1 -1
  49. package/dist/errors/{razorpay-unreachable.js → payment-provider-unreachable.js} +1 -1
  50. package/dist/features/addresses/schemas/address-form.d.ts +20 -20
  51. package/dist/features/addresses/schemas/index.d.ts +2 -2
  52. package/dist/features/admin/components/AdminSiteSettingsView.js +32 -16
  53. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  54. package/dist/features/admin/schemas/admin-ops-forms.d.ts +10 -10
  55. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  56. package/dist/features/admin/schemas/firestore.d.ts +17 -8
  57. package/dist/features/admin/schemas/firestore.js +1 -1
  58. package/dist/features/admin/schemas/nav-item-form.d.ts +2 -2
  59. package/dist/features/auctions/schemas/index.d.ts +2 -2
  60. package/dist/features/auth/schemas/index.d.ts +2 -2
  61. package/dist/features/before-after/schemas/index.d.ts +2 -2
  62. package/dist/features/blog/actions/blog-actions.d.ts +4 -4
  63. package/dist/features/blog/schemas/blog-form.d.ts +2 -2
  64. package/dist/features/blog/schemas/index.d.ts +4 -4
  65. package/dist/features/cart/schemas/index.d.ts +3 -3
  66. package/dist/features/catalogue/schemas/validation.d.ts +4 -4
  67. package/dist/features/categories/schemas/index.d.ts +2 -2
  68. package/dist/features/checkout/index.d.ts +0 -4
  69. package/dist/features/checkout/index.js +0 -3
  70. package/dist/features/checkout/types/index.d.ts +0 -25
  71. package/dist/features/checkout/types/index.js +1 -2
  72. package/dist/features/collections/schemas/index.d.ts +2 -2
  73. package/dist/features/consultation/schemas/index.d.ts +4 -4
  74. package/dist/features/corporate/schemas/index.d.ts +2 -2
  75. package/dist/features/events/schemas/index.d.ts +4 -4
  76. package/dist/features/grouped/schemas/index.d.ts +2 -2
  77. package/dist/features/homepage/schemas/index.d.ts +2 -2
  78. package/dist/features/lottery/schemas/zod.d.ts +4 -4
  79. package/dist/features/loyalty/schemas/index.d.ts +6 -6
  80. package/dist/features/orders/components/OrderPaymentSummary.d.ts +1 -1
  81. package/dist/features/orders/components/OrderPaymentSummary.js +5 -5
  82. package/dist/features/orders/components/RefundHistoryTable.js +1 -1
  83. package/dist/features/orders/repository/orders.repository.d.ts +10 -1
  84. package/dist/features/orders/repository/orders.repository.js +17 -1
  85. package/dist/features/orders/schemas/firestore.d.ts +11 -12
  86. package/dist/features/orders/schemas/firestore.js +0 -1
  87. package/dist/features/orders/schemas/index.d.ts +48 -48
  88. package/dist/features/orders/schemas/index.js +1 -1
  89. package/dist/features/orders/types/index.d.ts +1 -3
  90. package/dist/features/orders/types/index.js +1 -2
  91. package/dist/features/payments/manifest.js +1 -1
  92. package/dist/features/payments/repository/payout.repository.d.ts +1 -4
  93. package/dist/features/payments/repository/payout.repository.js +0 -29
  94. package/dist/features/payments/schemas/firestore.d.ts +8 -15
  95. package/dist/features/payments/schemas/firestore.js +7 -5
  96. package/dist/features/payments/schemas/index.d.ts +52 -125
  97. package/dist/features/payments/schemas/index.js +0 -58
  98. package/dist/features/payments/types/index.d.ts +2 -4
  99. package/dist/features/payments/types/index.js +1 -2
  100. package/dist/features/products/schemas/index.d.ts +14 -14
  101. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  102. package/dist/features/promotions/schemas/index.d.ts +20 -20
  103. package/dist/features/reviews/schemas/index.d.ts +8 -8
  104. package/dist/features/scams/schemas/index.d.ts +10 -10
  105. package/dist/features/search/action-index/settings-entries.js +4 -4
  106. package/dist/features/seller/schemas/index.d.ts +12 -12
  107. package/dist/features/seller/schemas/order-forms.d.ts +4 -4
  108. package/dist/features/shipments/schemas/validation.d.ts +28 -28
  109. package/dist/features/store-extensions/schemas/payout-method-form.d.ts +50 -50
  110. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  111. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +10 -10
  112. package/dist/features/support/schemas/index.d.ts +14 -14
  113. package/dist/features/tester/actions/checklist-item-actions.d.ts +4 -4
  114. package/dist/features/tester/schemas/checklist-item-form.d.ts +2 -2
  115. package/dist/features/tester/seed-data/_money-flows.js +145 -0
  116. package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +21 -2
  117. package/dist/features/tester/seed-data/authored/admin__site-system.js +38 -0
  118. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +10 -10
  119. package/dist/features/tester/seed-data/authored/buying__offers.js +11 -10
  120. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +1 -1
  121. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +24 -12
  122. package/dist/features/wishlist/schemas/index.d.ts +2 -2
  123. package/dist/index.d.ts +6 -28
  124. package/dist/index.js +8 -51
  125. package/dist/jobs.d.ts +1 -1
  126. package/dist/jobs.js +1 -1
  127. package/dist/providers/payment-phonepe/index.d.ts +117 -0
  128. package/dist/providers/payment-phonepe/index.js +221 -0
  129. package/dist/providers.d.ts +3 -2
  130. package/dist/providers.js +3 -2
  131. package/dist/schemas/registry.d.ts +163 -2623
  132. package/dist/schemas/registry.js +1 -6
  133. package/dist/seed/faq-seed-data.js +5 -5
  134. package/dist/seed/payouts-seed-data.js +3 -3
  135. package/dist/seed/site-settings-seed-data.js +7 -4
  136. package/dist/server-entry.d.ts +1 -2
  137. package/dist/server-entry.js +1 -3
  138. package/dist/server.d.ts +3 -9
  139. package/dist/server.js +5 -23
  140. package/dist/validation/schemas.d.ts +2 -2
  141. package/package.json +5 -4
  142. package/dist/_internal/server/features/payments/actions.d.ts +0 -30
  143. package/dist/_internal/server/features/payments/actions.js +0 -45
  144. package/dist/_internal/server/features/payments/data.d.ts +0 -13
  145. package/dist/_internal/server/features/payments/data.js +0 -20
  146. package/dist/_internal/server/features/payments/index.d.ts +0 -3
  147. package/dist/_internal/server/features/payments/index.js +0 -3
  148. package/dist/_internal/server/jobs/core/payoutBatch.d.ts +0 -2
  149. package/dist/_internal/server/jobs/core/payoutBatch.js +0 -120
  150. package/dist/_internal/server/jobs/handlers/payoutBatch.d.ts +0 -2
  151. package/dist/_internal/server/jobs/handlers/payoutBatch.js +0 -2
  152. package/dist/_internal/shared/features/payments/config.d.ts +0 -3
  153. package/dist/_internal/shared/features/payments/config.js +0 -3
  154. package/dist/contracts/client-payment-gateway.d.ts +0 -64
  155. package/dist/contracts/client-payment-gateway.js +0 -25
  156. package/dist/features/checkout/hooks/useCheckout.d.ts +0 -9
  157. package/dist/features/checkout/hooks/useCheckout.js +0 -24
  158. package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -72
  159. package/dist/features/checkout/hooks/useCheckoutApi.js +0 -47
  160. package/dist/features/checkout/hooks/usePaymentCheckout.d.ts +0 -77
  161. package/dist/features/checkout/hooks/usePaymentCheckout.js +0 -192
  162. package/dist/providers/payment-razorpay/index.d.ts +0 -115
  163. package/dist/providers/payment-razorpay/index.js +0 -208
  164. package/dist/schemas/webhooks/razorpay.d.ts +0 -2634
  165. package/dist/schemas/webhooks/razorpay.js +0 -104
@@ -11,14 +11,17 @@
11
11
  *
12
12
  * Usage:
13
13
  * const keys = await resolveKeys();
14
- * const razorpay = new Razorpay({ key_id: keys.razorpayKeyId, key_secret: keys.razorpayKeySecret });
14
+ * const client = StandardCheckoutClient.getInstance(keys.phonepeClientId, keys.phonepeClientSecret, Number(keys.phonepeClientVersion), env);
15
15
  */
16
16
  import { siteSettingsRepository } from "../repositories";
17
17
  import { normalizeError } from "../errors/normalize";
18
18
  const EMPTY_KEYS = {
19
- razorpayKeyId: "",
20
- razorpayKeySecret: "",
21
- razorpayWebhookSecret: "",
19
+ phonepeClientId: "",
20
+ phonepeClientSecret: "",
21
+ phonepeClientVersion: "",
22
+ phonepeEnvironment: "",
23
+ phonepeWebhookUsername: "",
24
+ phonepeWebhookPassword: "",
22
25
  resendApiKey: "",
23
26
  whatsappApiKey: "",
24
27
  whatsappPhoneNumberId: "",
@@ -46,9 +49,12 @@ export async function resolveKeys() {
46
49
  void normalizeError(_err); // Firestore unavailable — fall through to env-based defaults for backward compatibility
47
50
  }
48
51
  const value = {
49
- razorpayKeyId: db.razorpayKeyId || process.env.RAZORPAY_KEY_ID || "",
50
- razorpayKeySecret: db.razorpayKeySecret || process.env.RAZORPAY_KEY_SECRET || "",
51
- razorpayWebhookSecret: db.razorpayWebhookSecret || process.env.RAZORPAY_WEBHOOK_SECRET || "",
52
+ phonepeClientId: db.phonepeClientId || process.env.PHONEPE_CLIENT_ID || "",
53
+ phonepeClientSecret: db.phonepeClientSecret || process.env.PHONEPE_CLIENT_SECRET || "",
54
+ phonepeClientVersion: db.phonepeClientVersion || process.env.PHONEPE_CLIENT_VERSION || "1",
55
+ phonepeEnvironment: db.phonepeEnvironment || process.env.PHONEPE_ENVIRONMENT || "sandbox",
56
+ phonepeWebhookUsername: db.phonepeWebhookUsername || process.env.PHONEPE_WEBHOOK_USERNAME || "",
57
+ phonepeWebhookPassword: db.phonepeWebhookPassword || process.env.PHONEPE_WEBHOOK_PASSWORD || "",
52
58
  resendApiKey: db.resendApiKey || process.env.RESEND_API_KEY || "",
53
59
  whatsappApiKey: db.whatsappApiKey || process.env.WHATSAPP_API_KEY || "",
54
60
  whatsappPhoneNumberId: db.whatsappPhoneNumberId || process.env.WHATSAPP_PHONE_NUMBER_ID || "",
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Rupee/paise conversion helpers — gateway-agnostic.
3
+ *
4
+ * Every online payment gateway this project has integrated (Razorpay,
5
+ * PhonePe) bills in paise (India's smallest currency unit), so these live
6
+ * outside any specific provider directory.
7
+ */
8
+ /** Convert rupees (float) → paise (integer) for a gateway's amount field. */
9
+ export declare function rupeesToPaise(rupees: number): number;
10
+ /** Convert paise (integer) → rupees (float). */
11
+ export declare function paiseToRupees(paise: number): number;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Rupee/paise conversion helpers — gateway-agnostic.
3
+ *
4
+ * Every online payment gateway this project has integrated (Razorpay,
5
+ * PhonePe) bills in paise (India's smallest currency unit), so these live
6
+ * outside any specific provider directory.
7
+ */
8
+ /** Convert rupees (float) → paise (integer) for a gateway's amount field. */
9
+ export function rupeesToPaise(rupees) {
10
+ return Math.round(rupees * 100);
11
+ }
12
+ /** Convert paise (integer) → rupees (float). */
13
+ export function paiseToRupees(paise) {
14
+ return paise / 100;
15
+ }
@@ -9,7 +9,7 @@ export { AuthorizationError } from "./authorization-error";
9
9
  export { NotFoundError } from "./not-found-error";
10
10
  export { ConflictError } from "./conflict-error";
11
11
  export { DatabaseError } from "./database-error";
12
- export { RazorpayUnreachableError } from "./razorpay-unreachable";
12
+ export { PaymentProviderUnreachableError } from "./payment-provider-unreachable";
13
13
  export { handleApiError, logError, isAppError } from "./error-handler";
14
14
  export { mapToHttpError, HTTP_ERROR_CODES, type MappedError, type HttpErrorCode, } from "./error-mapping";
15
15
  export { ERROR_DISPLAY_MAP, getErrorDisplay, toUserMessage, GENERIC_USER_MESSAGE, type ErrorDisplayEntry, } from "./error-display-map";
@@ -12,7 +12,7 @@ export { AuthorizationError } from "./authorization-error";
12
12
  export { NotFoundError } from "./not-found-error";
13
13
  export { ConflictError } from "./conflict-error";
14
14
  export { DatabaseError } from "./database-error";
15
- export { RazorpayUnreachableError } from "./razorpay-unreachable";
15
+ export { PaymentProviderUnreachableError } from "./payment-provider-unreachable";
16
16
  // error-handler uses `next/server` — only import in server/API-route contexts
17
17
  export { handleApiError, logError, isAppError } from "./error-handler";
18
18
  // Code→HTTP mapper (server) — and the i18n / inline-field map (client-safe)
@@ -282,6 +282,7 @@ export declare const ERROR_MESSAGES: {
282
282
  readonly INSUFFICIENT_STOCK: "Insufficient stock for one or more items";
283
283
  readonly PAYMENT_FAILED: "Payment processing failed";
284
284
  readonly PAYMENT_DECLINED: "Payment was declined.";
285
+ readonly ORDER_PLACEMENT_IN_PROGRESS: "Your payment is still being confirmed — please wait a moment and refresh.";
285
286
  readonly PAYMENT_TRACKING_INIT_FAILED: "Failed to initialise payment tracking. Please check your order status.";
286
287
  readonly PAYMENT_TRACKING_CONNECTION_LOST: "Payment tracking connection lost. Please check your order status.";
287
288
  readonly PAYMENT_TRACKING_TIMED_OUT: "Payment confirmation timed out. Please check your order status.";
@@ -306,6 +306,7 @@ export const ERROR_MESSAGES = {
306
306
  INSUFFICIENT_STOCK: "Insufficient stock for one or more items",
307
307
  PAYMENT_FAILED: "Payment processing failed",
308
308
  PAYMENT_DECLINED: "Payment was declined.",
309
+ ORDER_PLACEMENT_IN_PROGRESS: "Your payment is still being confirmed — please wait a moment and refresh.",
309
310
  PAYMENT_TRACKING_INIT_FAILED: "Failed to initialise payment tracking. Please check your order status.",
310
311
  PAYMENT_TRACKING_CONNECTION_LOST: "Payment tracking connection lost. Please check your order status.",
311
312
  PAYMENT_TRACKING_TIMED_OUT: "Payment confirmation timed out. Please check your order status.",
@@ -1,4 +1,4 @@
1
1
  import { AppError } from "./base-error";
2
- export declare class RazorpayUnreachableError extends AppError {
2
+ export declare class PaymentProviderUnreachableError extends AppError {
3
3
  constructor(message?: string, data?: unknown);
4
4
  }
@@ -1,5 +1,5 @@
1
1
  import { AppError } from "./base-error";
2
- export class RazorpayUnreachableError extends AppError {
2
+ export class PaymentProviderUnreachableError extends AppError {
3
3
  constructor(message = "Payment provider unreachable", data) {
4
4
  super(503, message, "UPSTREAM_UNAVAILABLE", data);
5
5
  }
@@ -34,13 +34,13 @@ export declare const addressFormSchema: z.ZodEffects<z.ZodObject<{
34
34
  }, "strip", z.ZodTypeAny, {
35
35
  country: string;
36
36
  label: string;
37
- isDefault: boolean;
38
37
  fullName: string;
39
38
  phone: string;
40
39
  addressLine1: string;
41
40
  city: string;
42
41
  state: string;
43
42
  postalCode: string;
43
+ isDefault: boolean;
44
44
  addressLine2?: string | undefined;
45
45
  landmark?: string | undefined;
46
46
  }, {
@@ -58,13 +58,13 @@ export declare const addressFormSchema: z.ZodEffects<z.ZodObject<{
58
58
  }>, {
59
59
  country: string;
60
60
  label: string;
61
- isDefault: boolean;
62
61
  fullName: string;
63
62
  phone: string;
64
63
  addressLine1: string;
65
64
  city: string;
66
65
  state: string;
67
66
  postalCode: string;
67
+ isDefault: boolean;
68
68
  addressLine2?: string | undefined;
69
69
  landmark?: string | undefined;
70
70
  }, {
@@ -103,49 +103,49 @@ export declare const addressUpdateSchema: z.ZodEffects<z.ZodObject<{
103
103
  }, "strip", z.ZodTypeAny, {
104
104
  country?: string | undefined;
105
105
  label?: string | undefined;
106
- isDefault?: boolean | undefined;
107
106
  fullName?: string | undefined;
108
107
  phone?: string | undefined;
109
108
  addressLine1?: string | undefined;
110
109
  city?: string | undefined;
111
110
  state?: string | undefined;
112
111
  postalCode?: string | undefined;
112
+ isDefault?: boolean | undefined;
113
113
  addressLine2?: string | undefined;
114
114
  landmark?: string | undefined;
115
115
  }, {
116
116
  country?: string | undefined;
117
117
  label?: string | undefined;
118
- isDefault?: boolean | undefined;
119
118
  fullName?: string | undefined;
120
119
  phone?: string | undefined;
121
120
  addressLine1?: string | undefined;
122
121
  city?: string | undefined;
123
122
  state?: string | undefined;
124
123
  postalCode?: string | undefined;
124
+ isDefault?: boolean | undefined;
125
125
  addressLine2?: string | undefined;
126
126
  landmark?: string | undefined;
127
127
  }>, {
128
128
  country?: string | undefined;
129
129
  label?: string | undefined;
130
- isDefault?: boolean | undefined;
131
130
  fullName?: string | undefined;
132
131
  phone?: string | undefined;
133
132
  addressLine1?: string | undefined;
134
133
  city?: string | undefined;
135
134
  state?: string | undefined;
136
135
  postalCode?: string | undefined;
136
+ isDefault?: boolean | undefined;
137
137
  addressLine2?: string | undefined;
138
138
  landmark?: string | undefined;
139
139
  }, {
140
140
  country?: string | undefined;
141
141
  label?: string | undefined;
142
- isDefault?: boolean | undefined;
143
142
  fullName?: string | undefined;
144
143
  phone?: string | undefined;
145
144
  addressLine1?: string | undefined;
146
145
  city?: string | undefined;
147
146
  state?: string | undefined;
148
147
  postalCode?: string | undefined;
148
+ isDefault?: boolean | undefined;
149
149
  addressLine2?: string | undefined;
150
150
  landmark?: string | undefined;
151
151
  }>;
@@ -177,7 +177,6 @@ export declare const adminAddressCreateSchema: z.ZodEffects<z.ZodObject<{
177
177
  }, "strip", z.ZodTypeAny, {
178
178
  country: string;
179
179
  label: string;
180
- isDefault: boolean;
181
180
  ownerId: string;
182
181
  ownerType: "user" | "store";
183
182
  fullName: string;
@@ -186,6 +185,7 @@ export declare const adminAddressCreateSchema: z.ZodEffects<z.ZodObject<{
186
185
  city: string;
187
186
  state: string;
188
187
  postalCode: string;
188
+ isDefault: boolean;
189
189
  addressLine2?: string | undefined;
190
190
  landmark?: string | undefined;
191
191
  }, {
@@ -205,7 +205,6 @@ export declare const adminAddressCreateSchema: z.ZodEffects<z.ZodObject<{
205
205
  }>, {
206
206
  country: string;
207
207
  label: string;
208
- isDefault: boolean;
209
208
  ownerId: string;
210
209
  ownerType: "user" | "store";
211
210
  fullName: string;
@@ -214,6 +213,7 @@ export declare const adminAddressCreateSchema: z.ZodEffects<z.ZodObject<{
214
213
  city: string;
215
214
  state: string;
216
215
  postalCode: string;
216
+ isDefault: boolean;
217
217
  addressLine2?: string | undefined;
218
218
  landmark?: string | undefined;
219
219
  }, {
@@ -248,7 +248,6 @@ export declare const adminAddressUpdateSchema: z.ZodEffects<z.ZodObject<{
248
248
  }, "strip", z.ZodTypeAny, {
249
249
  country?: string | undefined;
250
250
  label?: string | undefined;
251
- isDefault?: boolean | undefined;
252
251
  ownerId?: string | undefined;
253
252
  ownerType?: "user" | "store" | undefined;
254
253
  fullName?: string | undefined;
@@ -257,12 +256,12 @@ export declare const adminAddressUpdateSchema: z.ZodEffects<z.ZodObject<{
257
256
  city?: string | undefined;
258
257
  state?: string | undefined;
259
258
  postalCode?: string | undefined;
259
+ isDefault?: boolean | undefined;
260
260
  addressLine2?: string | undefined;
261
261
  landmark?: string | undefined;
262
262
  }, {
263
263
  country?: string | undefined;
264
264
  label?: string | undefined;
265
- isDefault?: boolean | undefined;
266
265
  ownerId?: string | undefined;
267
266
  ownerType?: "user" | "store" | undefined;
268
267
  fullName?: string | undefined;
@@ -271,12 +270,12 @@ export declare const adminAddressUpdateSchema: z.ZodEffects<z.ZodObject<{
271
270
  city?: string | undefined;
272
271
  state?: string | undefined;
273
272
  postalCode?: string | undefined;
273
+ isDefault?: boolean | undefined;
274
274
  addressLine2?: string | undefined;
275
275
  landmark?: string | undefined;
276
276
  }>, {
277
277
  country?: string | undefined;
278
278
  label?: string | undefined;
279
- isDefault?: boolean | undefined;
280
279
  ownerId?: string | undefined;
281
280
  ownerType?: "user" | "store" | undefined;
282
281
  fullName?: string | undefined;
@@ -285,12 +284,12 @@ export declare const adminAddressUpdateSchema: z.ZodEffects<z.ZodObject<{
285
284
  city?: string | undefined;
286
285
  state?: string | undefined;
287
286
  postalCode?: string | undefined;
287
+ isDefault?: boolean | undefined;
288
288
  addressLine2?: string | undefined;
289
289
  landmark?: string | undefined;
290
290
  }, {
291
291
  country?: string | undefined;
292
292
  label?: string | undefined;
293
- isDefault?: boolean | undefined;
294
293
  ownerId?: string | undefined;
295
294
  ownerType?: "user" | "store" | undefined;
296
295
  fullName?: string | undefined;
@@ -299,6 +298,7 @@ export declare const adminAddressUpdateSchema: z.ZodEffects<z.ZodObject<{
299
298
  city?: string | undefined;
300
299
  state?: string | undefined;
301
300
  postalCode?: string | undefined;
301
+ isDefault?: boolean | undefined;
302
302
  addressLine2?: string | undefined;
303
303
  landmark?: string | undefined;
304
304
  }>;
@@ -337,8 +337,6 @@ export declare const adminAddressPatchSchema: z.ZodEffects<z.ZodObject<{
337
337
  country?: string | undefined;
338
338
  label?: string | undefined;
339
339
  action?: "ban" | "approve_unban" | "reject_unban" | undefined;
340
- isDefault?: boolean | undefined;
341
- banReason?: string | undefined;
342
340
  ownerId?: string | undefined;
343
341
  ownerType?: "user" | "store" | undefined;
344
342
  fullName?: string | undefined;
@@ -347,14 +345,14 @@ export declare const adminAddressPatchSchema: z.ZodEffects<z.ZodObject<{
347
345
  city?: string | undefined;
348
346
  state?: string | undefined;
349
347
  postalCode?: string | undefined;
348
+ isDefault?: boolean | undefined;
350
349
  addressLine2?: string | undefined;
351
350
  landmark?: string | undefined;
351
+ banReason?: string | undefined;
352
352
  }, {
353
353
  country?: string | undefined;
354
354
  label?: string | undefined;
355
355
  action?: "ban" | "approve_unban" | "reject_unban" | undefined;
356
- isDefault?: boolean | undefined;
357
- banReason?: string | undefined;
358
356
  ownerId?: string | undefined;
359
357
  ownerType?: "user" | "store" | undefined;
360
358
  fullName?: string | undefined;
@@ -363,14 +361,14 @@ export declare const adminAddressPatchSchema: z.ZodEffects<z.ZodObject<{
363
361
  city?: string | undefined;
364
362
  state?: string | undefined;
365
363
  postalCode?: string | undefined;
364
+ isDefault?: boolean | undefined;
366
365
  addressLine2?: string | undefined;
367
366
  landmark?: string | undefined;
367
+ banReason?: string | undefined;
368
368
  }>, {
369
369
  country?: string | undefined;
370
370
  label?: string | undefined;
371
371
  action?: "ban" | "approve_unban" | "reject_unban" | undefined;
372
- isDefault?: boolean | undefined;
373
- banReason?: string | undefined;
374
372
  ownerId?: string | undefined;
375
373
  ownerType?: "user" | "store" | undefined;
376
374
  fullName?: string | undefined;
@@ -379,14 +377,14 @@ export declare const adminAddressPatchSchema: z.ZodEffects<z.ZodObject<{
379
377
  city?: string | undefined;
380
378
  state?: string | undefined;
381
379
  postalCode?: string | undefined;
380
+ isDefault?: boolean | undefined;
382
381
  addressLine2?: string | undefined;
383
382
  landmark?: string | undefined;
383
+ banReason?: string | undefined;
384
384
  }, {
385
385
  country?: string | undefined;
386
386
  label?: string | undefined;
387
387
  action?: "ban" | "approve_unban" | "reject_unban" | undefined;
388
- isDefault?: boolean | undefined;
389
- banReason?: string | undefined;
390
388
  ownerId?: string | undefined;
391
389
  ownerType?: "user" | "store" | undefined;
392
390
  fullName?: string | undefined;
@@ -395,8 +393,10 @@ export declare const adminAddressPatchSchema: z.ZodEffects<z.ZodObject<{
395
393
  city?: string | undefined;
396
394
  state?: string | undefined;
397
395
  postalCode?: string | undefined;
396
+ isDefault?: boolean | undefined;
398
397
  addressLine2?: string | undefined;
399
398
  landmark?: string | undefined;
399
+ banReason?: string | undefined;
400
400
  }>;
401
401
  export type AdminAddressPatchValues = z.infer<typeof adminAddressPatchSchema>;
402
402
  /**
@@ -41,7 +41,6 @@ export declare const addressFirestoreSchema: z.ZodObject<{
41
41
  updatedAt: string | Date | z.objectOutputType<{
42
42
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
43
43
  }, z.ZodTypeAny, "passthrough">;
44
- isDefault: boolean;
45
44
  ownerId: string;
46
45
  ownerType: "user" | "store";
47
46
  fullName: string;
@@ -50,6 +49,7 @@ export declare const addressFirestoreSchema: z.ZodObject<{
50
49
  city: string;
51
50
  state: string;
52
51
  postalCode: string;
52
+ isDefault: boolean;
53
53
  addressLine2?: string | undefined;
54
54
  landmark?: string | undefined;
55
55
  }, {
@@ -62,7 +62,6 @@ export declare const addressFirestoreSchema: z.ZodObject<{
62
62
  updatedAt: string | Date | z.objectInputType<{
63
63
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
64
64
  }, z.ZodTypeAny, "passthrough">;
65
- isDefault: boolean;
66
65
  ownerId: string;
67
66
  ownerType: "user" | "store";
68
67
  fullName: string;
@@ -71,6 +70,7 @@ export declare const addressFirestoreSchema: z.ZodObject<{
71
70
  city: string;
72
71
  state: string;
73
72
  postalCode: string;
73
+ isDefault: boolean;
74
74
  addressLine2?: string | undefined;
75
75
  landmark?: string | undefined;
76
76
  }>;
@@ -210,9 +210,12 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
210
210
  const [platformShippingPercent, setPlatformShippingPercent] = React.useState(10);
211
211
  const [platformShippingFixedMin, setPlatformShippingFixedMin] = React.useState(0);
212
212
  // ⑧ Integrations
213
- const [razorpayKeyId, setRazorpayKeyId] = React.useState("");
214
- const [razorpayKeySecret, setRazorpayKeySecret] = React.useState("");
215
- const [razorpayWebhookSecret, setRazorpayWebhookSecret] = React.useState("");
213
+ const [phonepeClientId, setPhonepeClientId] = React.useState("");
214
+ const [phonepeClientSecret, setPhonepeClientSecret] = React.useState("");
215
+ const [phonepeClientVersion, setPhonepeClientVersion] = React.useState("1");
216
+ const [phonepeEnvironment, setPhonepeEnvironment] = React.useState("sandbox");
217
+ const [phonepeWebhookUsername, setPhonepeWebhookUsername] = React.useState("");
218
+ const [phonepeWebhookPassword, setPhonepeWebhookPassword] = React.useState("");
216
219
  const [smtpHost, setSmtpHost] = React.useState("");
217
220
  const [smtpPort, setSmtpPort] = React.useState("587");
218
221
  const [smtpUser, setSmtpUser] = React.useState("");
@@ -235,7 +238,7 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
235
238
  const [defaultCarrier, setDefaultCarrier] = React.useState("custom");
236
239
  const [maxDeliveryRadius, setMaxDeliveryRadius] = React.useState(0);
237
240
  // ⑨ Payment methods (siteSettings.payment — read by checkout for method eligibility)
238
- const [razorpayEnabled, setRazorpayEnabled] = React.useState(false);
241
+ const [phonepeEnabled, setPhonepeEnabled] = React.useState(false);
239
242
  const [upiManualEnabled, setUpiManualEnabled] = React.useState(true);
240
243
  const [codEnabled, setCodEnabled] = React.useState(true);
241
244
  const [otpCheckoutThreshold, setOtpCheckoutThreshold] = React.useState(5000);
@@ -417,9 +420,12 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
417
420
  setGstin(s.gst?.gstin ?? "");
418
421
  setGstLegalName(s.gst?.legalName ?? "");
419
422
  setGstAddress(s.gst?.address ?? "");
420
- setRazorpayKeyId(s.credentialsMasked?.razorpayKeyId ?? "");
421
- setRazorpayKeySecret(s.credentialsMasked?.razorpayKeySecret ?? "");
422
- setRazorpayWebhookSecret(s.credentialsMasked?.razorpayWebhookSecret ?? "");
423
+ setPhonepeClientId(s.credentialsMasked?.phonepeClientId ?? "");
424
+ setPhonepeClientSecret(s.credentialsMasked?.phonepeClientSecret ?? "");
425
+ setPhonepeClientVersion(s.credentialsMasked?.phonepeClientVersion ?? "1");
426
+ setPhonepeEnvironment(s.credentialsMasked?.phonepeEnvironment ?? "sandbox");
427
+ setPhonepeWebhookUsername(s.credentialsMasked?.phonepeWebhookUsername ?? "");
428
+ setPhonepeWebhookPassword(s.credentialsMasked?.phonepeWebhookPassword ?? "");
423
429
  setGoogleMapsApiKey(s.credentialsMasked?.googleMapsApiKey ?? "");
424
430
  setGooglePlaceId(s.credentialsMasked?.googlePlaceId ?? "");
425
431
  setSmtpHost(s.emailSettings?.host ?? "");
@@ -439,7 +445,7 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
439
445
  setFreeShippingThreshold(s.shipping?.freeShippingThreshold ?? 999);
440
446
  setDefaultCarrier(s.shipping?.defaultCarrier ?? "custom");
441
447
  setMaxDeliveryRadius(s.shipping?.maxDeliveryRadius ?? 0);
442
- setRazorpayEnabled(s.payment?.razorpayEnabled ?? false);
448
+ setPhonepeEnabled(s.payment?.phonepeEnabled ?? false);
443
449
  setUpiManualEnabled(s.payment?.upiManualEnabled ?? true);
444
450
  setCodEnabled(s.payment?.codEnabled ?? true);
445
451
  setOtpCheckoutThreshold(s.payment?.otpCheckoutThreshold ?? 5000);
@@ -508,9 +514,12 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
508
514
  setMsgCeilingEmail(s.messaging?.dailyCeiling?.email ?? 80);
509
515
  setMsgCeilingWhatsapp(s.messaging?.dailyCeiling?.whatsapp ?? 200);
510
516
  originalMaskedRef.current = {
511
- razorpayKeyId: s.credentialsMasked?.razorpayKeyId ?? "",
512
- razorpayKeySecret: s.credentialsMasked?.razorpayKeySecret ?? "",
513
- razorpayWebhookSecret: s.credentialsMasked?.razorpayWebhookSecret ?? "",
517
+ phonepeClientId: s.credentialsMasked?.phonepeClientId ?? "",
518
+ phonepeClientSecret: s.credentialsMasked?.phonepeClientSecret ?? "",
519
+ phonepeClientVersion: s.credentialsMasked?.phonepeClientVersion ?? "",
520
+ phonepeEnvironment: s.credentialsMasked?.phonepeEnvironment ?? "",
521
+ phonepeWebhookUsername: s.credentialsMasked?.phonepeWebhookUsername ?? "",
522
+ phonepeWebhookPassword: s.credentialsMasked?.phonepeWebhookPassword ?? "",
514
523
  googleMapsApiKey: s.credentialsMasked?.googleMapsApiKey ?? "",
515
524
  googlePlaceId: s.credentialsMasked?.googlePlaceId ?? "",
516
525
  metaPageAccessToken: s.credentialsMasked?.metaPageAccessToken ?? "",
@@ -616,9 +625,12 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
616
625
  // "" field, so an unedited tab never overwrites a real secret with its
617
626
  // own masked display string.
618
627
  credentials: {
619
- razorpayKeyId: maskedOrReal("razorpayKeyId", razorpayKeyId),
620
- razorpayKeySecret: maskedOrReal("razorpayKeySecret", razorpayKeySecret),
621
- razorpayWebhookSecret: maskedOrReal("razorpayWebhookSecret", razorpayWebhookSecret),
628
+ phonepeClientId: maskedOrReal("phonepeClientId", phonepeClientId),
629
+ phonepeClientSecret: maskedOrReal("phonepeClientSecret", phonepeClientSecret),
630
+ phonepeClientVersion: maskedOrReal("phonepeClientVersion", phonepeClientVersion),
631
+ phonepeEnvironment: maskedOrReal("phonepeEnvironment", phonepeEnvironment),
632
+ phonepeWebhookUsername: maskedOrReal("phonepeWebhookUsername", phonepeWebhookUsername),
633
+ phonepeWebhookPassword: maskedOrReal("phonepeWebhookPassword", phonepeWebhookPassword),
622
634
  googleMapsApiKey: maskedOrReal("googleMapsApiKey", googleMapsApiKey),
623
635
  googlePlaceId: maskedOrReal("googlePlaceId", googlePlaceId),
624
636
  metaPageAccessToken: maskedOrReal("metaPageAccessToken", metaPageAccessToken),
@@ -665,7 +677,7 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
665
677
  },
666
678
  integrations: { googleAnalyticsId: gaMeasurementId, facebookPixelId: fbPixelId, gtmContainerId },
667
679
  shipping: { freeShippingThreshold, defaultCarrier, maxDeliveryRadius },
668
- payment: { razorpayEnabled, upiManualEnabled, codEnabled, otpCheckoutThreshold },
680
+ payment: { phonepeEnabled, upiManualEnabled, codEnabled, otpCheckoutThreshold },
669
681
  auctionConfig: { bidIncrementTiers: bidIncrementTiers, autoExtendWindowMinutes: autoExtendWindow, settlementGracePeriodHours: settlementGrace },
670
682
  platformLimits: { maxProductsPerStore, maxCustomFieldsPerProduct: maxCustomFields, maxCustomSectionsPerProduct: maxCustomSections, orderCancellationWindowHours: orderCancelWindow },
671
683
  legalPages: { terms: termsHtml, privacy: privacyHtml, refundPolicy: refundHtml, shipping: shippingPolicyHtml, cookies: cookieHtml, ethics: ethicsHtml, codeOfConduct: conductHtml },
@@ -720,6 +732,10 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
720
732
  { label: "Bluedart", value: "bluedart" },
721
733
  { label: "FedEx", value: "fedex" },
722
734
  ];
735
+ const PHONEPE_ENVIRONMENT_OPTIONS = [
736
+ { label: "Sandbox (test)", value: "sandbox" },
737
+ { label: "Production (live)", value: "production" },
738
+ ];
723
739
  const LISTING_TYPE_KEYS = ["standard", "auction", "pre-order", "prize-draw", "bundle", "classified", "digital-code", "live"];
724
740
  const CATEGORY_TYPE_KEYS = ["category", "sublisting", "brand", "bundle"];
725
741
  const NOTIF_TYPE_OPTIONS = NOTIFICATION_TYPE_TABS.filter((t) => t.id !== "All").map((t) => ({ value: t.id, label: t.label }));
@@ -767,7 +783,7 @@ export function AdminSiteSettingsView({ labels = {}, ...rest }) {
767
783
  { label: "Top right", value: "top-right" },
768
784
  { label: "Bottom left", value: "bottom-left" },
769
785
  { label: "Bottom right", value: "bottom-right" },
770
- ], value: watermarkPosition, onValueChange: (v) => setWatermarkPosition(v), disabled: watermarkUseCustomOffset }), _jsx(Toggle, { checked: watermarkUseCustomOffset, onChange: setWatermarkUseCustomOffset, label: "Use a custom X/Y offset instead" }), watermarkUseCustomOffset && (_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "X offset (%) \u2014 + right / \u2212 left of center", value: String(watermarkOffsetX), onChange: (e) => setWatermarkOffsetX(Math.max(-45, Math.min(45, parseInt(e.target.value) || 0))), type: "number", min: -45, max: 45 }), _jsx(Input, { label: "Y offset (%) \u2014 + down / \u2212 up from center", value: String(watermarkOffsetY), onChange: (e) => setWatermarkOffsetY(Math.max(-45, Math.min(45, parseInt(e.target.value) || 0))), type: "number", min: -45, max: 45 })] })), _jsxs(Stack, { gap: "xs", surface: "muted", rounded: "lg", border: "default", padding: "md", children: [_jsx(Text, { size: "xs", color: "muted", children: "Preview (text watermark only)" }), _jsx(Row, { surface: "default", justify: "end", align: "end", className: `relative h-32 ${__O.hidden}`, rounded: "default", children: _jsx(Span, { ref: watermarkPreviewRef, weight: "medium", color: "faint", padding: "1", className: "select-none", children: watermarkText }) })] })] }) }), _jsx(TabsContent, { value: "fees", children: _jsxs(SettingsTabForm, { id: "fees", label: "Fees", children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Platform fee \u2014 our cut (%)", helperText: "% charged on order value. Buyer pays this.", value: String(platformFeePercent), onChange: (e) => setPlatformFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "GST on platform fee (%)", helperText: "Applied to our fee only (not full order). Usually 18%.", value: String(gstPercent), onChange: (e) => setGstPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "Razorpay gateway cost (%)", helperText: "Gateway's own fee \u2014 absorbed by platform, not passed through.", value: String(gatewayFeePercent), onChange: (e) => setGatewayFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 10, step: 0.01 }), _jsx(Input, { label: "Minimum transaction fee (\u20B9)", helperText: "Per-transaction floor. Total charge will never be below base + this.", value: String(minimumTransactionFee), onChange: (e) => setMinimumTransactionFee(parseFloat(e.target.value) || 0), type: "number", min: 0, step: 0.01 }), _jsx(Input, { label: "Maximum platform fee (\u20B9)", helperText: "Ceiling on the buyer's platform commission, charged once per checkout on every payment method. GST is calculated on the capped amount.", value: String(platformFeeMax), onChange: (e) => setPlatformFeeMax(parseFloat(e.target.value) || 0), type: "number", min: 0, step: 0.01 }), _jsx(Input, { label: "Seller payout hold (days)", value: String(payoutHoldDays), onChange: (e) => setPayoutHoldDays(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Minimum payout amount (\u20B9)", value: String(minPayoutAmount), onChange: (e) => setMinPayoutAmount(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Auction listing fee (\u20B9)", value: String(auctionListingFee), onChange: (e) => setAuctionListingFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Pre-order listing fee (\u20B9)", value: String(preOrderListingFee), onChange: (e) => setPreOrderListingFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Featured slot fee (\u20B9)", value: String(featuredSlotFee), onChange: (e) => setFeaturedSlotFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Promoted slot fee (\u20B9)", value: String(promotedSlotFee), onChange: (e) => setPromotedSlotFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "COD deposit (%)", helperText: "% of order collected upfront on COD orders; remainder paid on delivery.", value: String(codDepositPercent), onChange: (e) => setCodDepositPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 })] }), _jsx(Toggle, { checked: whatsappNotifyFeeEnabled, onChange: setWhatsappNotifyFeeEnabled, label: "Offer the WhatsApp order-updates addon at checkout" }), _jsx(Grid, { cols: 2, gap: "md", children: _jsx(Input, { label: "WhatsApp addon fee (\u20B9)", helperText: "Flat fee charged to the buyer when they opt in. Requires WhatsApp credentials + at least one approved template \u2014 see the WhatsApp tab.", value: String(whatsappNotifyFee), onChange: (e) => setWhatsappNotifyFee(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !whatsappNotifyFeeEnabled }) }), _jsx(Toggle, { checked: giftWrapFeeEnabled, onChange: setGiftWrapFeeEnabled, label: "Offer the gift-wrap addon at checkout" }), _jsx(Grid, { cols: 2, gap: "md", children: _jsx(Input, { label: "Gift wrap fee (\u20B9)", helperText: "Flat fee charged to the buyer when they opt in.", value: String(giftWrapFee), onChange: (e) => setGiftWrapFee(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !giftWrapFeeEnabled }) }), _jsx(Toggle, { checked: shipmentProtectionFeeEnabled, onChange: setShipmentProtectionFeeEnabled, label: "Offer the shipment-protection addon at checkout" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Shipment protection (%)", helperText: "% of order subtotal, charged when the buyer opts in.", value: String(shipmentProtectionFeePercent), onChange: (e) => setShipmentProtectionFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1, disabled: !shipmentProtectionFeeEnabled }), _jsx(Input, { label: "Shipment protection minimum (\u20B9)", helperText: "Floor for the shipment-protection fee.", value: String(shipmentProtectionFeeMin), onChange: (e) => setShipmentProtectionFeeMin(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !shipmentProtectionFeeEnabled })] })] }) }), _jsx(TabsContent, { value: "procurement", children: _jsxs(SettingsTabForm, { id: "procurement", label: "Procurement", children: [_jsx(Text, { size: "xs", color: "muted", children: "Used to compute each procurement shipment's labor cost (hours spent \u00D7 hourly rate) and its estimated processing time (hours spent \u00F7 max hours/day)." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Hourly rate (\u20B9)", helperText: "Your effective hourly wage for sorting/categorizing/listing a shipment.", value: String(laborHourlyRate), onChange: (e) => setLaborHourlyRate(Math.round((parseFloat(e.target.value) || 0) * 100) / 100), type: "number", min: 0 }), _jsx(Input, { label: "Max hours per day", helperText: "Used only to project how many days a shipment's tracked hours will take.", value: String(laborMaxHoursPerDay), onChange: (e) => setLaborMaxHoursPerDay(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 24 })] })] }) }), _jsx(TabsContent, { value: "emi", children: _jsxs(SettingsTabForm, { id: "emi", label: "Emi", children: [_jsx(Text, { size: "xs", color: "muted", children: "A seller must also opt in via their own Payout Settings for EMI to appear at checkout on their items. See the \"How EMI Works\" public page for buyer-facing copy." }), _jsx(Toggle, { checked: emiEnabled, onChange: setEmiEnabled, label: "Enable EMI platform-wide" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Minimum order value (\u20B9)", helperText: "A seller's cart subtotal must exceed this for EMI to appear as an option.", value: String(emiMinOrderValue), onChange: (e) => setEmiMinOrderValue(Math.round((parseFloat(e.target.value) || 0) * 100) / 100), type: "number", min: 0 }), _jsx(Input, { label: "Tenure options (months, comma-separated)", helperText: "e.g. 2,3,4,5,6", value: emiTenureOptionsText, onChange: (e) => setEmiTenureOptionsText(e.target.value) }), _jsx(Input, { label: "Token / down-payment (%)", helperText: "Collected upfront at checkout.", value: String(emiTokenPercent), onChange: (e) => setEmiTokenPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100 }), _jsx(Input, { label: "Billing day (1\u201310)", helperText: "Day of month each installment is due.", value: String(emiBillingDay), onChange: (e) => setEmiBillingDay(parseFloat(e.target.value) || 1), type: "number", min: 1, max: 10 }), _jsx(Input, { label: "Surcharge (% of principal per month)", helperText: "The 'excess EMI fee' the buyer pays for spreading payment.", value: String(emiSurchargePercentPerMonth), onChange: (e) => setEmiSurchargePercentPerMonth(parseFloat(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Seller's share of surcharge (%)", helperText: "The rest of the surcharge goes to the platform.", value: String(emiSurchargeSellerSharePercent), onChange: (e) => setEmiSurchargeSellerSharePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100 })] })] }) }), _jsx(TabsContent, { value: "gst", children: _jsxs(SettingsTabForm, { id: "gst", label: "Gst", children: [_jsx(Text, { size: "xs", color: "muted", children: "Required before enabling GST-inclusive checkout (P-8). Also set a GST rate + HSN code on each taxable product for the tax breakdown to appear." }), _jsx(Toggle, { checked: gstEnabled, onChange: setGstEnabled, label: "Enable GST on checkout" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "GSTIN", helperText: "15-character GST Identification Number.", value: gstin, onChange: (e) => setGstin(e.target.value), placeholder: "29AAAAA0000A1Z5", maxLength: 15 }), _jsx(Input, { label: "Legal name", helperText: "Registered business name for invoices.", value: gstLegalName, onChange: (e) => setGstLegalName(e.target.value), placeholder: "LetItRip Collectibles Pvt Ltd" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Registered address" }), _jsx(Textarea, { value: gstAddress, onChange: (e) => setGstAddress(e.target.value), placeholder: "Registered business address for GST invoices\u2026", rows: 3 })] })] }) }), _jsx(TabsContent, { value: "listings", children: _jsxs(SettingsTabForm, { id: "listings", label: "Listings", children: [_jsx(Text, { size: "xs", color: "muted", children: "Which listing and category types the marketplace offers. A disabled type is hidden from every browse surface and rejected on create and add-to-cart \u2014 existing data is untouched, it just becomes unreachable until re-enabled." }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Listing types" }), _jsx(Text, { size: "xs", color: "muted", children: "Disabled types are hidden from listings and reject create/add-to-cart." }), _jsx(Grid, { cols: 2, gap: "sm", children: LISTING_TYPE_KEYS.map((key) => (_jsx(Toggle, { label: key, checked: listingTypeFlags[key] ?? true, onChange: (v) => setListingTypeFlags((prev) => ({ ...prev, [key]: v })) }, key))) })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Category types" }), _jsx(Grid, { cols: 2, gap: "sm", children: CATEGORY_TYPE_KEYS.map((key) => (_jsx(Toggle, { label: key, checked: categoryTypeFlags[key] ?? true, onChange: (v) => setCategoryTypeFlags((prev) => ({ ...prev, [key]: v })) }, key))) })] })] }) }), _jsx(TabsContent, { value: "integrations", children: _jsxs(SettingsTabForm, { id: "integrations", label: "Integrations", children: [_jsx(Text, { size: "xs", color: "muted", children: "Keys are masked in transit and stored encrypted. Click Reveal to view." }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Razorpay" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Razorpay Key ID", value: razorpayKeyId, onChange: setRazorpayKeyId, placeholder: "rzp_live_\u2026" }), _jsx(MaskedInput, { label: "Razorpay Key Secret", value: razorpayKeySecret, onChange: setRazorpayKeySecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(MaskedInput, { label: "Razorpay Webhook Secret", value: razorpayWebhookSecret, onChange: setRazorpayWebhookSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "SMTP / Email" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "SMTP host", value: smtpHost, onChange: (e) => setSmtpHost(e.target.value), placeholder: "smtp.sendgrid.net" }), _jsx(Input, { label: "SMTP port", value: smtpPort, onChange: (e) => setSmtpPort(e.target.value), type: "number", placeholder: "587" }), _jsx(Input, { label: "SMTP user", value: smtpUser, onChange: (e) => setSmtpUser(e.target.value), placeholder: "apikey" })] }), _jsx(Input, { label: "From address", value: smtpFrom, onChange: (e) => setSmtpFrom(e.target.value), placeholder: "noreply@letitrip.in", type: "email" }), _jsx(Text, { size: "xs", color: "muted", children: "Transactional email is delivered through Resend \u2014 set the Resend API key below. These SMTP fields are stored but not currently used for delivery." })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Google Places (store reviews)" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Google Maps API key", value: googleMapsApiKey, onChange: setGoogleMapsApiKey, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(Input, { label: "Default Google Place ID", value: googlePlaceId, onChange: (e) => setGooglePlaceId(e.target.value), placeholder: "ChIJ\u2026" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Analytics & Tracking" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Google Analytics ID", value: gaMeasurementId, onChange: (e) => setGaMeasurementId(e.target.value), placeholder: "G-XXXXXXXXXX" }), _jsx(Input, { label: "Facebook Pixel ID", value: fbPixelId, onChange: (e) => setFbPixelId(e.target.value), placeholder: "XXXXXXXXXXXXXXXX" }), _jsx(Input, { label: "GTM Container ID", value: gtmContainerId, onChange: (e) => setGtmContainerId(e.target.value), placeholder: "GTM-XXXXXXX" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Meta (Instagram & Facebook Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Used by the Social Feed section to fetch Instagram and Facebook posts via Meta Graph API v19." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Page Access Token", value: metaPageAccessToken, onChange: setMetaPageAccessToken, placeholder: "EAAxxxxxxx\u2026" }), _jsx(Input, { label: "Page ID (or handle)", value: metaPageId, onChange: (e) => setMetaPageId(e.target.value), placeholder: "letitrip" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "TikTok for Developers (Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Client credentials + long-lived access token from TikTok for Developers. Used to list your account's public videos." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Client Key", value: tiktokClientKey, onChange: setTiktokClientKey, placeholder: "aw\u2026" }), _jsx(MaskedInput, { label: "Client Secret", value: tiktokClientSecret, onChange: setTiktokClientSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(MaskedInput, { label: "Access Token (long-lived)", value: tiktokAccessToken, onChange: setTiktokAccessToken, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "DeviantArt OAuth2 (Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Client credentials for DeviantArt gallery fetching (client-credentials OAuth2 flow \u2014 no user login required)." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Client ID", value: deviantartClientId, onChange: setDeviantartClientId, placeholder: "1234" }), _jsx(MaskedInput, { label: "Client Secret", value: deviantartClientSecret, onChange: setDeviantartClientSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] })] }) }), _jsx(TabsContent, { value: "shipping", children: _jsxs(SettingsTabForm, { id: "shipping", label: "Shipping", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Payment methods" }), _jsx(Div, { id: "setting-razorpay-enabled", children: _jsx(Toggle, { label: "Razorpay (online card/UPI) enabled \u2014 disabled by default, manual payment is the default", checked: razorpayEnabled, onChange: setRazorpayEnabled }) }), _jsx(Div, { id: "setting-manual-payment-enabled", children: _jsx(Toggle, { label: "Manual UPI/bank transfer enabled", checked: upiManualEnabled, onChange: setUpiManualEnabled }) }), _jsx(Div, { id: "setting-cod-enabled", children: _jsx(Toggle, { label: "Cash on delivery (COD) enabled", checked: codEnabled, onChange: setCodEnabled }) }), _jsx(Input, { label: "Free shipping threshold (\u20B9)", value: String(freeShippingThreshold), onChange: (e) => setFreeShippingThreshold(parseInt(e.target.value) || 0), type: "number", min: 0, helperText: "Orders above this amount get free shipping." }), _jsx(Select, { label: "Default carrier", options: CARRIER_OPTIONS, value: defaultCarrier, onValueChange: setDefaultCarrier }), _jsx(Input, { label: "Max delivery radius (km, 0 = no limit)", value: String(maxDeliveryRadius), onChange: (e) => setMaxDeliveryRadius(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "High-value checkout OTP threshold (\u20B9)", helperText: "Carts at or above this subtotal require an extra OTP verification step before payment (0 = disabled).", value: String(otpCheckoutThreshold), onChange: (e) => setOtpCheckoutThreshold(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Text, { size: "sm", weight: "medium", color: "muted", className: "pt-[var(--appkit-space-2)]", children: "Seller shipping charge defaults" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Seller shipping fixed (\u20B9)", helperText: "Flat shipping charge collected on the seller's behalf.", value: String(sellerShippingFixed), onChange: (e) => setSellerShippingFixed(parseFloat(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Platform shipping (%)", helperText: "Platform's own shipping markup, as a % of order value.", value: String(platformShippingPercent), onChange: (e) => setPlatformShippingPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "Platform shipping minimum (\u20B9)", helperText: "Floor for the platform shipping markup.", value: String(platformShippingFixedMin), onChange: (e) => setPlatformShippingFixedMin(parseFloat(e.target.value) || 0), type: "number", min: 0 })] })] }) }), _jsx(TabsContent, { value: "auction", children: _jsxs(SettingsTabForm, { id: "auction", label: "Auction", children: [_jsxs(Stack, { gap: "sm", rounded: "lg", border: "default", padding: "sm", children: [_jsx(Text, { size: "xs", weight: "medium", color: "muted", children: "Bid increment tiers" }), _jsx(Text, { size: "xs", color: "muted", children: "The minimum jump a new bid must clear, based on the current bid amount. A seller's per-listing override can require more than the matching tier, but can never undercut it." }), bidIncrementTiers.map((tier, i) => {
786
+ ], value: watermarkPosition, onValueChange: (v) => setWatermarkPosition(v), disabled: watermarkUseCustomOffset }), _jsx(Toggle, { checked: watermarkUseCustomOffset, onChange: setWatermarkUseCustomOffset, label: "Use a custom X/Y offset instead" }), watermarkUseCustomOffset && (_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "X offset (%) \u2014 + right / \u2212 left of center", value: String(watermarkOffsetX), onChange: (e) => setWatermarkOffsetX(Math.max(-45, Math.min(45, parseInt(e.target.value) || 0))), type: "number", min: -45, max: 45 }), _jsx(Input, { label: "Y offset (%) \u2014 + down / \u2212 up from center", value: String(watermarkOffsetY), onChange: (e) => setWatermarkOffsetY(Math.max(-45, Math.min(45, parseInt(e.target.value) || 0))), type: "number", min: -45, max: 45 })] })), _jsxs(Stack, { gap: "xs", surface: "muted", rounded: "lg", border: "default", padding: "md", children: [_jsx(Text, { size: "xs", color: "muted", children: "Preview (text watermark only)" }), _jsx(Row, { surface: "default", justify: "end", align: "end", className: `relative h-32 ${__O.hidden}`, rounded: "default", children: _jsx(Span, { ref: watermarkPreviewRef, weight: "medium", color: "faint", padding: "1", className: "select-none", children: watermarkText }) })] })] }) }), _jsx(TabsContent, { value: "fees", children: _jsxs(SettingsTabForm, { id: "fees", label: "Fees", children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Platform fee \u2014 our cut (%)", helperText: "% charged on order value. Buyer pays this.", value: String(platformFeePercent), onChange: (e) => setPlatformFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "GST on platform fee (%)", helperText: "Applied to our fee only (not full order). Usually 18%.", value: String(gstPercent), onChange: (e) => setGstPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "PhonePe gateway cost (%)", helperText: "Gateway's own fee \u2014 absorbed by platform, not passed through.", value: String(gatewayFeePercent), onChange: (e) => setGatewayFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 10, step: 0.01 }), _jsx(Input, { label: "Minimum transaction fee (\u20B9)", helperText: "Per-transaction floor. Total charge will never be below base + this.", value: String(minimumTransactionFee), onChange: (e) => setMinimumTransactionFee(parseFloat(e.target.value) || 0), type: "number", min: 0, step: 0.01 }), _jsx(Input, { label: "Maximum platform fee (\u20B9)", helperText: "Ceiling on the buyer's platform commission, charged once per checkout on every payment method. GST is calculated on the capped amount.", value: String(platformFeeMax), onChange: (e) => setPlatformFeeMax(parseFloat(e.target.value) || 0), type: "number", min: 0, step: 0.01 }), _jsx(Input, { label: "Seller payout hold (days)", value: String(payoutHoldDays), onChange: (e) => setPayoutHoldDays(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Minimum payout amount (\u20B9)", value: String(minPayoutAmount), onChange: (e) => setMinPayoutAmount(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Auction listing fee (\u20B9)", value: String(auctionListingFee), onChange: (e) => setAuctionListingFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Pre-order listing fee (\u20B9)", value: String(preOrderListingFee), onChange: (e) => setPreOrderListingFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Featured slot fee (\u20B9)", value: String(featuredSlotFee), onChange: (e) => setFeaturedSlotFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Promoted slot fee (\u20B9)", value: String(promotedSlotFee), onChange: (e) => setPromotedSlotFee(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "COD deposit (%)", helperText: "% of order collected upfront on COD orders; remainder paid on delivery.", value: String(codDepositPercent), onChange: (e) => setCodDepositPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 })] }), _jsx(Toggle, { checked: whatsappNotifyFeeEnabled, onChange: setWhatsappNotifyFeeEnabled, label: "Offer the WhatsApp order-updates addon at checkout" }), _jsx(Grid, { cols: 2, gap: "md", children: _jsx(Input, { label: "WhatsApp addon fee (\u20B9)", helperText: "Flat fee charged to the buyer when they opt in. Requires WhatsApp credentials + at least one approved template \u2014 see the WhatsApp tab.", value: String(whatsappNotifyFee), onChange: (e) => setWhatsappNotifyFee(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !whatsappNotifyFeeEnabled }) }), _jsx(Toggle, { checked: giftWrapFeeEnabled, onChange: setGiftWrapFeeEnabled, label: "Offer the gift-wrap addon at checkout" }), _jsx(Grid, { cols: 2, gap: "md", children: _jsx(Input, { label: "Gift wrap fee (\u20B9)", helperText: "Flat fee charged to the buyer when they opt in.", value: String(giftWrapFee), onChange: (e) => setGiftWrapFee(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !giftWrapFeeEnabled }) }), _jsx(Toggle, { checked: shipmentProtectionFeeEnabled, onChange: setShipmentProtectionFeeEnabled, label: "Offer the shipment-protection addon at checkout" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Shipment protection (%)", helperText: "% of order subtotal, charged when the buyer opts in.", value: String(shipmentProtectionFeePercent), onChange: (e) => setShipmentProtectionFeePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1, disabled: !shipmentProtectionFeeEnabled }), _jsx(Input, { label: "Shipment protection minimum (\u20B9)", helperText: "Floor for the shipment-protection fee.", value: String(shipmentProtectionFeeMin), onChange: (e) => setShipmentProtectionFeeMin(parseFloat(e.target.value) || 0), type: "number", min: 0, disabled: !shipmentProtectionFeeEnabled })] })] }) }), _jsx(TabsContent, { value: "procurement", children: _jsxs(SettingsTabForm, { id: "procurement", label: "Procurement", children: [_jsx(Text, { size: "xs", color: "muted", children: "Used to compute each procurement shipment's labor cost (hours spent \u00D7 hourly rate) and its estimated processing time (hours spent \u00F7 max hours/day)." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Hourly rate (\u20B9)", helperText: "Your effective hourly wage for sorting/categorizing/listing a shipment.", value: String(laborHourlyRate), onChange: (e) => setLaborHourlyRate(Math.round((parseFloat(e.target.value) || 0) * 100) / 100), type: "number", min: 0 }), _jsx(Input, { label: "Max hours per day", helperText: "Used only to project how many days a shipment's tracked hours will take.", value: String(laborMaxHoursPerDay), onChange: (e) => setLaborMaxHoursPerDay(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 24 })] })] }) }), _jsx(TabsContent, { value: "emi", children: _jsxs(SettingsTabForm, { id: "emi", label: "Emi", children: [_jsx(Text, { size: "xs", color: "muted", children: "A seller must also opt in via their own Payout Settings for EMI to appear at checkout on their items. See the \"How EMI Works\" public page for buyer-facing copy." }), _jsx(Toggle, { checked: emiEnabled, onChange: setEmiEnabled, label: "Enable EMI platform-wide" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Minimum order value (\u20B9)", helperText: "A seller's cart subtotal must exceed this for EMI to appear as an option.", value: String(emiMinOrderValue), onChange: (e) => setEmiMinOrderValue(Math.round((parseFloat(e.target.value) || 0) * 100) / 100), type: "number", min: 0 }), _jsx(Input, { label: "Tenure options (months, comma-separated)", helperText: "e.g. 2,3,4,5,6", value: emiTenureOptionsText, onChange: (e) => setEmiTenureOptionsText(e.target.value) }), _jsx(Input, { label: "Token / down-payment (%)", helperText: "Collected upfront at checkout.", value: String(emiTokenPercent), onChange: (e) => setEmiTokenPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100 }), _jsx(Input, { label: "Billing day (1\u201310)", helperText: "Day of month each installment is due.", value: String(emiBillingDay), onChange: (e) => setEmiBillingDay(parseFloat(e.target.value) || 1), type: "number", min: 1, max: 10 }), _jsx(Input, { label: "Surcharge (% of principal per month)", helperText: "The 'excess EMI fee' the buyer pays for spreading payment.", value: String(emiSurchargePercentPerMonth), onChange: (e) => setEmiSurchargePercentPerMonth(parseFloat(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Seller's share of surcharge (%)", helperText: "The rest of the surcharge goes to the platform.", value: String(emiSurchargeSellerSharePercent), onChange: (e) => setEmiSurchargeSellerSharePercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100 })] })] }) }), _jsx(TabsContent, { value: "gst", children: _jsxs(SettingsTabForm, { id: "gst", label: "Gst", children: [_jsx(Text, { size: "xs", color: "muted", children: "Required before enabling GST-inclusive checkout (P-8). Also set a GST rate + HSN code on each taxable product for the tax breakdown to appear." }), _jsx(Toggle, { checked: gstEnabled, onChange: setGstEnabled, label: "Enable GST on checkout" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "GSTIN", helperText: "15-character GST Identification Number.", value: gstin, onChange: (e) => setGstin(e.target.value), placeholder: "29AAAAA0000A1Z5", maxLength: 15 }), _jsx(Input, { label: "Legal name", helperText: "Registered business name for invoices.", value: gstLegalName, onChange: (e) => setGstLegalName(e.target.value), placeholder: "LetItRip Collectibles Pvt Ltd" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Registered address" }), _jsx(Textarea, { value: gstAddress, onChange: (e) => setGstAddress(e.target.value), placeholder: "Registered business address for GST invoices\u2026", rows: 3 })] })] }) }), _jsx(TabsContent, { value: "listings", children: _jsxs(SettingsTabForm, { id: "listings", label: "Listings", children: [_jsx(Text, { size: "xs", color: "muted", children: "Which listing and category types the marketplace offers. A disabled type is hidden from every browse surface and rejected on create and add-to-cart \u2014 existing data is untouched, it just becomes unreachable until re-enabled." }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Listing types" }), _jsx(Text, { size: "xs", color: "muted", children: "Disabled types are hidden from listings and reject create/add-to-cart." }), _jsx(Grid, { cols: 2, gap: "sm", children: LISTING_TYPE_KEYS.map((key) => (_jsx(Toggle, { label: key, checked: listingTypeFlags[key] ?? true, onChange: (v) => setListingTypeFlags((prev) => ({ ...prev, [key]: v })) }, key))) })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Category types" }), _jsx(Grid, { cols: 2, gap: "sm", children: CATEGORY_TYPE_KEYS.map((key) => (_jsx(Toggle, { label: key, checked: categoryTypeFlags[key] ?? true, onChange: (v) => setCategoryTypeFlags((prev) => ({ ...prev, [key]: v })) }, key))) })] })] }) }), _jsx(TabsContent, { value: "integrations", children: _jsxs(SettingsTabForm, { id: "integrations", label: "Integrations", children: [_jsx(Text, { size: "xs", color: "muted", children: "Keys are masked in transit and stored encrypted. Click Reveal to view." }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "PhonePe" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "PhonePe Client ID", value: phonepeClientId, onChange: setPhonepeClientId, placeholder: "MERCHANTID_\u2026" }), _jsx(MaskedInput, { label: "PhonePe Client Secret", value: phonepeClientSecret, onChange: setPhonepeClientSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(Input, { label: "PhonePe Client Version", value: phonepeClientVersion, onChange: (e) => setPhonepeClientVersion(e.target.value), placeholder: "1" }), _jsx(Select, { label: "PhonePe Environment", options: PHONEPE_ENVIRONMENT_OPTIONS, value: phonepeEnvironment, onValueChange: setPhonepeEnvironment }), _jsx(MaskedInput, { label: "PhonePe Webhook Username", value: phonepeWebhookUsername, onChange: setPhonepeWebhookUsername, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(MaskedInput, { label: "PhonePe Webhook Password", value: phonepeWebhookPassword, onChange: setPhonepeWebhookPassword, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "SMTP / Email" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "SMTP host", value: smtpHost, onChange: (e) => setSmtpHost(e.target.value), placeholder: "smtp.sendgrid.net" }), _jsx(Input, { label: "SMTP port", value: smtpPort, onChange: (e) => setSmtpPort(e.target.value), type: "number", placeholder: "587" }), _jsx(Input, { label: "SMTP user", value: smtpUser, onChange: (e) => setSmtpUser(e.target.value), placeholder: "apikey" })] }), _jsx(Input, { label: "From address", value: smtpFrom, onChange: (e) => setSmtpFrom(e.target.value), placeholder: "noreply@letitrip.in", type: "email" }), _jsx(Text, { size: "xs", color: "muted", children: "Transactional email is delivered through Resend \u2014 set the Resend API key below. These SMTP fields are stored but not currently used for delivery." })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Google Places (store reviews)" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Google Maps API key", value: googleMapsApiKey, onChange: setGoogleMapsApiKey, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(Input, { label: "Default Google Place ID", value: googlePlaceId, onChange: (e) => setGooglePlaceId(e.target.value), placeholder: "ChIJ\u2026" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Analytics & Tracking" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Google Analytics ID", value: gaMeasurementId, onChange: (e) => setGaMeasurementId(e.target.value), placeholder: "G-XXXXXXXXXX" }), _jsx(Input, { label: "Facebook Pixel ID", value: fbPixelId, onChange: (e) => setFbPixelId(e.target.value), placeholder: "XXXXXXXXXXXXXXXX" }), _jsx(Input, { label: "GTM Container ID", value: gtmContainerId, onChange: (e) => setGtmContainerId(e.target.value), placeholder: "GTM-XXXXXXX" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Meta (Instagram & Facebook Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Used by the Social Feed section to fetch Instagram and Facebook posts via Meta Graph API v19." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Page Access Token", value: metaPageAccessToken, onChange: setMetaPageAccessToken, placeholder: "EAAxxxxxxx\u2026" }), _jsx(Input, { label: "Page ID (or handle)", value: metaPageId, onChange: (e) => setMetaPageId(e.target.value), placeholder: "letitrip" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "TikTok for Developers (Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Client credentials + long-lived access token from TikTok for Developers. Used to list your account's public videos." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Client Key", value: tiktokClientKey, onChange: setTiktokClientKey, placeholder: "aw\u2026" }), _jsx(MaskedInput, { label: "Client Secret", value: tiktokClientSecret, onChange: setTiktokClientSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }), _jsx(MaskedInput, { label: "Access Token (long-lived)", value: tiktokAccessToken, onChange: setTiktokAccessToken, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "DeviantArt OAuth2 (Social Feed)" }), _jsx(Text, { size: "xs", color: "muted", children: "Client credentials for DeviantArt gallery fetching (client-credentials OAuth2 flow \u2014 no user login required)." }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(MaskedInput, { label: "Client ID", value: deviantartClientId, onChange: setDeviantartClientId, placeholder: "1234" }), _jsx(MaskedInput, { label: "Client Secret", value: deviantartClientSecret, onChange: setDeviantartClientSecret, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })] })] })] }) }), _jsx(TabsContent, { value: "shipping", children: _jsxs(SettingsTabForm, { id: "shipping", label: "Shipping", children: [_jsx(Text, { size: "sm", weight: "medium", color: "muted", children: "Payment methods" }), _jsx(Div, { id: "setting-phonepe-enabled", children: _jsx(Toggle, { label: "PhonePe (online card/UPI) enabled \u2014 disabled by default, manual payment is the default", checked: phonepeEnabled, onChange: setPhonepeEnabled }) }), _jsx(Div, { id: "setting-manual-payment-enabled", children: _jsx(Toggle, { label: "Manual UPI/bank transfer enabled", checked: upiManualEnabled, onChange: setUpiManualEnabled }) }), _jsx(Div, { id: "setting-cod-enabled", children: _jsx(Toggle, { label: "Cash on delivery (COD) enabled", checked: codEnabled, onChange: setCodEnabled }) }), _jsx(Input, { label: "Free shipping threshold (\u20B9)", value: String(freeShippingThreshold), onChange: (e) => setFreeShippingThreshold(parseInt(e.target.value) || 0), type: "number", min: 0, helperText: "Orders above this amount get free shipping." }), _jsx(Select, { label: "Default carrier", options: CARRIER_OPTIONS, value: defaultCarrier, onValueChange: setDefaultCarrier }), _jsx(Input, { label: "Max delivery radius (km, 0 = no limit)", value: String(maxDeliveryRadius), onChange: (e) => setMaxDeliveryRadius(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "High-value checkout OTP threshold (\u20B9)", helperText: "Carts at or above this subtotal require an extra OTP verification step before payment (0 = disabled).", value: String(otpCheckoutThreshold), onChange: (e) => setOtpCheckoutThreshold(parseInt(e.target.value) || 0), type: "number", min: 0 }), _jsx(Text, { size: "sm", weight: "medium", color: "muted", className: "pt-[var(--appkit-space-2)]", children: "Seller shipping charge defaults" }), _jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(Input, { label: "Seller shipping fixed (\u20B9)", helperText: "Flat shipping charge collected on the seller's behalf.", value: String(sellerShippingFixed), onChange: (e) => setSellerShippingFixed(parseFloat(e.target.value) || 0), type: "number", min: 0 }), _jsx(Input, { label: "Platform shipping (%)", helperText: "Platform's own shipping markup, as a % of order value.", value: String(platformShippingPercent), onChange: (e) => setPlatformShippingPercent(parseFloat(e.target.value) || 0), type: "number", min: 0, max: 100, step: 0.1 }), _jsx(Input, { label: "Platform shipping minimum (\u20B9)", helperText: "Floor for the platform shipping markup.", value: String(platformShippingFixedMin), onChange: (e) => setPlatformShippingFixedMin(parseFloat(e.target.value) || 0), type: "number", min: 0 })] })] }) }), _jsx(TabsContent, { value: "auction", children: _jsxs(SettingsTabForm, { id: "auction", label: "Auction", children: [_jsxs(Stack, { gap: "sm", rounded: "lg", border: "default", padding: "sm", children: [_jsx(Text, { size: "xs", weight: "medium", color: "muted", children: "Bid increment tiers" }), _jsx(Text, { size: "xs", color: "muted", children: "The minimum jump a new bid must clear, based on the current bid amount. A seller's per-listing override can require more than the matching tier, but can never undercut it." }), bidIncrementTiers.map((tier, i) => {
771
787
  const isLast = i === bidIncrementTiers.length - 1;
772
788
  return (_jsxs(Grid, { align: "end", gap: "xs", className: "grid-cols-12", children: [_jsx(Div, { className: "col-span-5", children: isLast ? (_jsxs(_Fragment, { children: [_jsx(Text, { size: "xs", weight: "medium", className: "mb-1", children: "Up to (\u20B9)" }), _jsx(Text, { size: "sm", color: "muted", children: "and above" })] })) : (_jsx(Input, { label: "Up to (\u20B9)", type: "number", min: 1, value: String(tier.upTo ?? ""), onChange: (e) => setBidIncrementTiers(bidIncrementTiers.map((t, j) => j === i ? { ...t, upTo: parseInt(e.target.value) || 0 } : t)) })) }), _jsx(Div, { className: "col-span-5", children: _jsx(Input, { label: "Increment (\u20B9)", type: "number", min: 1, value: String(tier.increment), onChange: (e) => setBidIncrementTiers(bidIncrementTiers.map((t, j) => j === i ? { ...t, increment: parseInt(e.target.value) || 0 } : t)) }) }), _jsx(Row, { centered: true, className: "col-span-2", padding: "b-xs", children: _jsx(Button, { variant: "ghost", type: "button", disabled: bidIncrementTiers.length <= 1, onClick: () => setBidIncrementTiers(bidIncrementTiers.filter((_, j) => j !== i)), "aria-label": "Remove tier", children: "\u00D7" }) })] }, i));
773
789
  }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setBidIncrementTiers([
@@ -107,7 +107,7 @@ export declare const SITE_SETTINGS_TABS: readonly [{
107
107
  readonly description: "Which listing types sellers may create, and their defaults.";
108
108
  readonly keywords: ["listing types", "auctions on", "enable", "categories"];
109
109
  }];
110
- export declare const SITE_SETTINGS_TAB_IDS: ("about" | "shipping" | "whatsapp" | "notifications" | "contact" | "auction" | "seo" | "listings" | "appearance" | "emi" | "gst" | "watermark" | "integrations" | "limits" | "announcement" | "branding" | "themes" | "fees" | "legal" | "procurement")[];
110
+ export declare const SITE_SETTINGS_TAB_IDS: ("about" | "shipping" | "notifications" | "contact" | "auction" | "seo" | "listings" | "appearance" | "emi" | "gst" | "watermark" | "integrations" | "limits" | "announcement" | "whatsapp" | "branding" | "themes" | "fees" | "legal" | "procurement")[];
111
111
  /**
112
112
  * The union `?tab=` is validated against.
113
113
  *