@webbycrown/webbycommerce 1.0.0 → 1.0.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.
- package/README.md +94 -7
- package/dist/_chunks/{Settings-BTffXkdF.mjs → Settings-CM-LMCQo.mjs} +61 -15
- package/dist/_chunks/{Settings-CHavEmCV.js → Settings-TToktNAy.js} +60 -14
- package/dist/_chunks/{en-CN5945VW.mjs → en-BsbZxjAR.mjs} +61 -8
- package/dist/_chunks/{en-Dj8IzRXD.js → en-CwvqDxF2.js} +61 -8
- package/dist/_chunks/{index-BFH1VuAA.mjs → index-Cgnv1DYN.mjs} +48 -5
- package/dist/_chunks/{index-DXM6qeJr.js → index-D0Y_VvWO.js} +48 -5
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +1142 -254
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,8 +46,40 @@ module.exports = ({ env }) => ({
|
|
|
46
46
|
});
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
|
|
49
50
|
## ⚙️ Initial Setup
|
|
50
51
|
|
|
52
|
+
### 0. (Optional) Seed Demo Data
|
|
53
|
+
|
|
54
|
+
You can populate your store with sample products/categories/etc using any of the following options:
|
|
55
|
+
|
|
56
|
+
#### Option A: Run the setup and answer `y`
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx strapi-ecommerce-setup
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
When prompted **"Would you like to seed example data? (y/n):"**, answer **`y`**.
|
|
63
|
+
|
|
64
|
+
#### Option B: Seed from Strapi Admin (works even if you answered `n`)
|
|
65
|
+
|
|
66
|
+
- Go to **Strapi Admin → Settings → Advanced Ecommerce**
|
|
67
|
+
- Click **"Seed Demo Data"**
|
|
68
|
+
|
|
69
|
+
#### Option C: Seed via `.env` flag (programmatic / CI-friendly)
|
|
70
|
+
|
|
71
|
+
Add this to your Strapi project’s `.env` and then start Strapi:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
STRAPI_PLUGIN_ADVANCED_ECOMMERCE_SEED_DATA=true
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm run develop
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
After the demo data is seeded once, set it back to `false` (or remove it) to avoid reseeding on every startup.
|
|
82
|
+
|
|
51
83
|
### 1. Enable Permissions
|
|
52
84
|
|
|
53
85
|
After installation, navigate to **Settings → Users & Permissions → Roles** and select the **Public** role (or any role you want to grant access).
|
|
@@ -77,7 +109,7 @@ Navigate to **Settings → WebbyCommerce** in the Strapi admin panel. You'll fin
|
|
|
77
109
|
|
|
78
110
|
### 3. User Schema Extension
|
|
79
111
|
|
|
80
|
-
The plugin automatically extends the user schema with ecommerce-specific fields.
|
|
112
|
+
The plugin automatically extends the user schema with ecommerce-specific fields. The plugin will attempt to automatically add OTP fields to the user schema when it starts up.
|
|
81
113
|
|
|
82
114
|
**Required Fields:**
|
|
83
115
|
- `username` (string, required, unique)
|
|
@@ -90,11 +122,53 @@ The plugin automatically extends the user schema with ecommerce-specific fields.
|
|
|
90
122
|
- `display_name` (string)
|
|
91
123
|
- `company_name` (string)
|
|
92
124
|
|
|
93
|
-
**OTP Fields (if using OTP authentication):**
|
|
94
|
-
- `otp` (integer)
|
|
95
|
-
- `isOtpVerified` (boolean, default: false)
|
|
96
|
-
|
|
97
|
-
|
|
125
|
+
**OTP Fields (required if using OTP authentication):**
|
|
126
|
+
- `otp` (integer, nullable) - Stores the OTP code
|
|
127
|
+
- `isOtpVerified` (boolean, default: false) - Tracks if OTP has been verified
|
|
128
|
+
|
|
129
|
+
#### Automatic Schema Extension
|
|
130
|
+
|
|
131
|
+
The plugin automatically adds OTP fields to the user schema on startup. If you see an error about OTP fields not being available, you may need to manually extend the schema.
|
|
132
|
+
|
|
133
|
+
#### Manual Schema Extension (if automatic extension fails)
|
|
134
|
+
|
|
135
|
+
If the automatic schema extension doesn't work, create a schema extension file in your main Strapi project:
|
|
136
|
+
|
|
137
|
+
1. Create the directory structure:
|
|
138
|
+
```
|
|
139
|
+
src/extensions/users-permissions/content-types/user/
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. Create `schema.json` in that directory with the following content:
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"kind": "collectionType",
|
|
146
|
+
"collectionName": "up_users",
|
|
147
|
+
"info": {
|
|
148
|
+
"name": "user",
|
|
149
|
+
"description": "",
|
|
150
|
+
"singularName": "user",
|
|
151
|
+
"pluralName": "users"
|
|
152
|
+
},
|
|
153
|
+
"options": {},
|
|
154
|
+
"pluginOptions": {},
|
|
155
|
+
"attributes": {
|
|
156
|
+
"otp": {
|
|
157
|
+
"type": "integer",
|
|
158
|
+
"required": false,
|
|
159
|
+
"private": true
|
|
160
|
+
},
|
|
161
|
+
"isOtpVerified": {
|
|
162
|
+
"type": "boolean",
|
|
163
|
+
"default": false,
|
|
164
|
+
"required": false,
|
|
165
|
+
"private": true
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
3. Restart Strapi to apply the schema changes.
|
|
98
172
|
|
|
99
173
|
### 4. Address Content Type
|
|
100
174
|
|
|
@@ -506,7 +580,20 @@ Authorization: Bearer YOUR_JWT_TOKEN
|
|
|
506
580
|
|
|
507
581
|
## 📜 Changelog
|
|
508
582
|
|
|
509
|
-
|
|
583
|
+
## [1.0.2] – Patch Release
|
|
584
|
+
|
|
585
|
+
### Fixed
|
|
586
|
+
- Fix critical bugs
|
|
587
|
+
|
|
588
|
+
## [1.0.1] – Patch Release
|
|
589
|
+
|
|
590
|
+
### Changed
|
|
591
|
+
- Updated README documentation
|
|
592
|
+
|
|
593
|
+
### Fixed
|
|
594
|
+
- Resolved reported bugs
|
|
595
|
+
|
|
596
|
+
## [1.0.0] – Initial Stable Release
|
|
510
597
|
|
|
511
598
|
🎉 First production-ready release of WebbyCommerce, a complete ecommerce backend plugin for Strapi CMS.
|
|
512
599
|
|
|
@@ -2,8 +2,8 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import React__default, { useContext, useRef, useCallback, useDebugValue, useMemo, useState, useEffect, useLayoutEffect, createContext as createContext$1, createElement, useReducer } from "react";
|
|
4
4
|
import { useIntl, FormattedMessage } from "react-intl";
|
|
5
|
-
import { Flex, Box, Popover, Typography, Button, LinkButton, Link as Link$1, Portal, Alert, Field, SubNav, Badge, TextInput, Pagination, PreviousLink, Dots, PageLink, NextLink, Modal,
|
|
6
|
-
import { P as PLUGIN_ID } from "./index-
|
|
5
|
+
import { Flex, Box, Popover, Typography, Button, LinkButton, Link as Link$1, Portal, Alert, Field, SubNav, Badge, TextInput, Pagination, PreviousLink, Dots, PageLink, NextLink, Modal, Main } from "@strapi/design-system";
|
|
6
|
+
import { P as PLUGIN_ID } from "./index-Cgnv1DYN.mjs";
|
|
7
7
|
import { WarningCircle, CaretDown, Trash } from "@strapi/icons";
|
|
8
8
|
import "react-dom/client";
|
|
9
9
|
import ReactDOM, { unstable_batchedUpdates as unstable_batchedUpdates$1 } from "react-dom";
|
|
@@ -19103,6 +19103,7 @@ new QueryClient({
|
|
|
19103
19103
|
});
|
|
19104
19104
|
const HEIGHT_TOP_NAVIGATION = "6.4rem";
|
|
19105
19105
|
const HEIGHT_TOP_NAVIGATION_MEDIUM = "5.6rem";
|
|
19106
|
+
const WIDTH_SIDE_NAVIGATION = "23.2rem";
|
|
19106
19107
|
styled(Alert)`
|
|
19107
19108
|
& > div:first-child {
|
|
19108
19109
|
display: none;
|
|
@@ -21337,6 +21338,8 @@ flatRest(function(object2, paths) {
|
|
|
21337
21338
|
styled(Field.Root)`
|
|
21338
21339
|
height: 3.2rem;
|
|
21339
21340
|
width: 3.2rem;
|
|
21341
|
+
align-items: center;
|
|
21342
|
+
justify-content: center;
|
|
21340
21343
|
|
|
21341
21344
|
> label,
|
|
21342
21345
|
~ input {
|
|
@@ -21387,21 +21390,30 @@ create().shape({
|
|
|
21387
21390
|
if (!value || typeof value !== "string") return true;
|
|
21388
21391
|
const byteSize = getByteSize(value);
|
|
21389
21392
|
return byteSize <= 72;
|
|
21390
|
-
}).
|
|
21393
|
+
}).test("lowercase", {
|
|
21391
21394
|
message: {
|
|
21392
21395
|
id: "components.Input.error.contain.lowercase",
|
|
21393
21396
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21394
21397
|
}
|
|
21395
|
-
})
|
|
21398
|
+
}, (value) => {
|
|
21399
|
+
if (!value) return true;
|
|
21400
|
+
return /[a-z]/.test(value);
|
|
21401
|
+
}).test("uppercase", {
|
|
21396
21402
|
message: {
|
|
21397
21403
|
id: "components.Input.error.contain.uppercase",
|
|
21398
21404
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21399
21405
|
}
|
|
21400
|
-
})
|
|
21406
|
+
}, (value) => {
|
|
21407
|
+
if (!value) return true;
|
|
21408
|
+
return /[A-Z]/.test(value);
|
|
21409
|
+
}).test("number", {
|
|
21401
21410
|
message: {
|
|
21402
21411
|
id: "components.Input.error.contain.number",
|
|
21403
21412
|
defaultMessage: "Password must contain at least 1 number"
|
|
21404
21413
|
}
|
|
21414
|
+
}, (value) => {
|
|
21415
|
+
if (!value) return true;
|
|
21416
|
+
return /\d/.test(value);
|
|
21405
21417
|
}).required({
|
|
21406
21418
|
id: errorsTrads.required.id,
|
|
21407
21419
|
defaultMessage: "Password is required"
|
|
@@ -21439,21 +21451,30 @@ create().shape({
|
|
|
21439
21451
|
}, function(value) {
|
|
21440
21452
|
if (!value) return true;
|
|
21441
21453
|
return new TextEncoder().encode(value).length <= 72;
|
|
21442
|
-
}).
|
|
21454
|
+
}).test("lowercase", {
|
|
21443
21455
|
message: {
|
|
21444
21456
|
id: "components.Input.error.contain.lowercase",
|
|
21445
21457
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21446
21458
|
}
|
|
21447
|
-
})
|
|
21459
|
+
}, (value) => {
|
|
21460
|
+
if (!value) return true;
|
|
21461
|
+
return /[a-z]/.test(value);
|
|
21462
|
+
}).test("uppercase", {
|
|
21448
21463
|
message: {
|
|
21449
21464
|
id: "components.Input.error.contain.uppercase",
|
|
21450
21465
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21451
21466
|
}
|
|
21452
|
-
})
|
|
21467
|
+
}, (value) => {
|
|
21468
|
+
if (!value) return true;
|
|
21469
|
+
return /[A-Z]/.test(value);
|
|
21470
|
+
}).test("number", {
|
|
21453
21471
|
message: {
|
|
21454
21472
|
id: "components.Input.error.contain.number",
|
|
21455
21473
|
defaultMessage: "Password must contain at least 1 number"
|
|
21456
21474
|
}
|
|
21475
|
+
}, (value) => {
|
|
21476
|
+
if (!value) return true;
|
|
21477
|
+
return /\d/.test(value);
|
|
21457
21478
|
}).required({
|
|
21458
21479
|
id: errorsTrads.required.id,
|
|
21459
21480
|
defaultMessage: "Password is required"
|
|
@@ -21496,21 +21517,30 @@ create().shape({
|
|
|
21496
21517
|
if (!value || typeof value !== "string") return true;
|
|
21497
21518
|
const byteSize = getByteSize(value);
|
|
21498
21519
|
return byteSize <= 72;
|
|
21499
|
-
}).
|
|
21520
|
+
}).test("lowercase", {
|
|
21500
21521
|
message: {
|
|
21501
21522
|
id: "components.Input.error.contain.lowercase",
|
|
21502
21523
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21503
21524
|
}
|
|
21504
|
-
})
|
|
21525
|
+
}, (value) => {
|
|
21526
|
+
if (!value) return true;
|
|
21527
|
+
return /[a-z]/.test(value);
|
|
21528
|
+
}).test("uppercase", {
|
|
21505
21529
|
message: {
|
|
21506
21530
|
id: "components.Input.error.contain.uppercase",
|
|
21507
21531
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21508
21532
|
}
|
|
21509
|
-
})
|
|
21533
|
+
}, (value) => {
|
|
21534
|
+
if (!value) return true;
|
|
21535
|
+
return /[A-Z]/.test(value);
|
|
21536
|
+
}).test("number", {
|
|
21510
21537
|
message: {
|
|
21511
21538
|
id: "components.Input.error.contain.number",
|
|
21512
21539
|
defaultMessage: "Password must contain at least 1 number"
|
|
21513
21540
|
}
|
|
21541
|
+
}, (value) => {
|
|
21542
|
+
if (!value) return true;
|
|
21543
|
+
return /\d/.test(value);
|
|
21514
21544
|
}).required({
|
|
21515
21545
|
id: errorsTrads.required.id,
|
|
21516
21546
|
defaultMessage: "Password is required"
|
|
@@ -21570,7 +21600,7 @@ const MainSubNav = styled(SubNav)`
|
|
|
21570
21600
|
z-index: 2;
|
|
21571
21601
|
|
|
21572
21602
|
${({ theme }) => theme.breakpoints.medium} {
|
|
21573
|
-
width:
|
|
21603
|
+
width: ${WIDTH_SIDE_NAVIGATION};
|
|
21574
21604
|
position: sticky;
|
|
21575
21605
|
top: 0;
|
|
21576
21606
|
border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
@@ -21663,12 +21693,28 @@ styled(Box)`
|
|
|
21663
21693
|
}
|
|
21664
21694
|
`;
|
|
21665
21695
|
styled(Badge)`
|
|
21696
|
+
width: 100%;
|
|
21666
21697
|
background: linear-gradient(
|
|
21667
21698
|
90deg,
|
|
21668
21699
|
${({ theme }) => theme.colors.primary600} 0%,
|
|
21669
21700
|
${({ theme }) => theme.colors.alternative600} 121.48%
|
|
21670
21701
|
);
|
|
21671
|
-
padding:
|
|
21702
|
+
padding: 1.1rem 1rem;
|
|
21703
|
+
|
|
21704
|
+
${({ theme }) => theme.breakpoints.small} {
|
|
21705
|
+
padding: 1.2rem 1rem;
|
|
21706
|
+
}
|
|
21707
|
+
${({ theme }) => theme.breakpoints.medium} {
|
|
21708
|
+
padding: 0.4rem 1rem;
|
|
21709
|
+
}
|
|
21710
|
+
`;
|
|
21711
|
+
styled(Typography)`
|
|
21712
|
+
font-size: 1.2rem;
|
|
21713
|
+
|
|
21714
|
+
${({ theme }) => theme.breakpoints.small} {
|
|
21715
|
+
font-size: 1.4rem;
|
|
21716
|
+
line-height: 1.6rem;
|
|
21717
|
+
}
|
|
21672
21718
|
`;
|
|
21673
21719
|
const useFetchClient = () => {
|
|
21674
21720
|
const controller = React.useRef(null);
|
|
@@ -31137,7 +31183,7 @@ const Settings = () => {
|
|
|
31137
31183
|
const { formatMessage } = useIntl();
|
|
31138
31184
|
const [activeView, setActiveView] = useState("configure");
|
|
31139
31185
|
const titleId = `${PLUGIN_ID}-settings-title`;
|
|
31140
|
-
return /* @__PURE__ */ jsx(
|
|
31186
|
+
return /* @__PURE__ */ jsx(Main, { labelledBy: titleId, children: /* @__PURE__ */ jsxs(Box, { padding: 8, background: "neutral100", children: [
|
|
31141
31187
|
/* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(Typography, { id: titleId, variant: "alpha", as: "h1", children: formatMessage({
|
|
31142
31188
|
id: `${PLUGIN_ID}.settings.section`,
|
|
31143
31189
|
defaultMessage: "Advanced Ecommerce"
|
|
@@ -31206,7 +31252,7 @@ const Settings = () => {
|
|
|
31206
31252
|
activeView === "smtp" && /* @__PURE__ */ jsx(SmtpContent, {}),
|
|
31207
31253
|
activeView === "api-collections" && /* @__PURE__ */ jsx(ApiCollectionsContent, {})
|
|
31208
31254
|
] })
|
|
31209
|
-
] }) })
|
|
31255
|
+
] }) });
|
|
31210
31256
|
};
|
|
31211
31257
|
export {
|
|
31212
31258
|
Settings as default
|
|
@@ -4,7 +4,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const React = require("react");
|
|
5
5
|
const reactIntl = require("react-intl");
|
|
6
6
|
const designSystem = require("@strapi/design-system");
|
|
7
|
-
const index = require("./index-
|
|
7
|
+
const index = require("./index-D0Y_VvWO.js");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
require("react-dom/client");
|
|
10
10
|
const ReactDOM = require("react-dom");
|
|
@@ -19145,6 +19145,7 @@ new QueryClient({
|
|
|
19145
19145
|
});
|
|
19146
19146
|
const HEIGHT_TOP_NAVIGATION = "6.4rem";
|
|
19147
19147
|
const HEIGHT_TOP_NAVIGATION_MEDIUM = "5.6rem";
|
|
19148
|
+
const WIDTH_SIDE_NAVIGATION = "23.2rem";
|
|
19148
19149
|
styled.styled(designSystem.Alert)`
|
|
19149
19150
|
& > div:first-child {
|
|
19150
19151
|
display: none;
|
|
@@ -21379,6 +21380,8 @@ flatRest(function(object2, paths) {
|
|
|
21379
21380
|
styled.styled(designSystem.Field.Root)`
|
|
21380
21381
|
height: 3.2rem;
|
|
21381
21382
|
width: 3.2rem;
|
|
21383
|
+
align-items: center;
|
|
21384
|
+
justify-content: center;
|
|
21382
21385
|
|
|
21383
21386
|
> label,
|
|
21384
21387
|
~ input {
|
|
@@ -21429,21 +21432,30 @@ create().shape({
|
|
|
21429
21432
|
if (!value || typeof value !== "string") return true;
|
|
21430
21433
|
const byteSize = getByteSize(value);
|
|
21431
21434
|
return byteSize <= 72;
|
|
21432
|
-
}).
|
|
21435
|
+
}).test("lowercase", {
|
|
21433
21436
|
message: {
|
|
21434
21437
|
id: "components.Input.error.contain.lowercase",
|
|
21435
21438
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21436
21439
|
}
|
|
21437
|
-
})
|
|
21440
|
+
}, (value) => {
|
|
21441
|
+
if (!value) return true;
|
|
21442
|
+
return /[a-z]/.test(value);
|
|
21443
|
+
}).test("uppercase", {
|
|
21438
21444
|
message: {
|
|
21439
21445
|
id: "components.Input.error.contain.uppercase",
|
|
21440
21446
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21441
21447
|
}
|
|
21442
|
-
})
|
|
21448
|
+
}, (value) => {
|
|
21449
|
+
if (!value) return true;
|
|
21450
|
+
return /[A-Z]/.test(value);
|
|
21451
|
+
}).test("number", {
|
|
21443
21452
|
message: {
|
|
21444
21453
|
id: "components.Input.error.contain.number",
|
|
21445
21454
|
defaultMessage: "Password must contain at least 1 number"
|
|
21446
21455
|
}
|
|
21456
|
+
}, (value) => {
|
|
21457
|
+
if (!value) return true;
|
|
21458
|
+
return /\d/.test(value);
|
|
21447
21459
|
}).required({
|
|
21448
21460
|
id: errorsTrads.required.id,
|
|
21449
21461
|
defaultMessage: "Password is required"
|
|
@@ -21481,21 +21493,30 @@ create().shape({
|
|
|
21481
21493
|
}, function(value) {
|
|
21482
21494
|
if (!value) return true;
|
|
21483
21495
|
return new TextEncoder().encode(value).length <= 72;
|
|
21484
|
-
}).
|
|
21496
|
+
}).test("lowercase", {
|
|
21485
21497
|
message: {
|
|
21486
21498
|
id: "components.Input.error.contain.lowercase",
|
|
21487
21499
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21488
21500
|
}
|
|
21489
|
-
})
|
|
21501
|
+
}, (value) => {
|
|
21502
|
+
if (!value) return true;
|
|
21503
|
+
return /[a-z]/.test(value);
|
|
21504
|
+
}).test("uppercase", {
|
|
21490
21505
|
message: {
|
|
21491
21506
|
id: "components.Input.error.contain.uppercase",
|
|
21492
21507
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21493
21508
|
}
|
|
21494
|
-
})
|
|
21509
|
+
}, (value) => {
|
|
21510
|
+
if (!value) return true;
|
|
21511
|
+
return /[A-Z]/.test(value);
|
|
21512
|
+
}).test("number", {
|
|
21495
21513
|
message: {
|
|
21496
21514
|
id: "components.Input.error.contain.number",
|
|
21497
21515
|
defaultMessage: "Password must contain at least 1 number"
|
|
21498
21516
|
}
|
|
21517
|
+
}, (value) => {
|
|
21518
|
+
if (!value) return true;
|
|
21519
|
+
return /\d/.test(value);
|
|
21499
21520
|
}).required({
|
|
21500
21521
|
id: errorsTrads.required.id,
|
|
21501
21522
|
defaultMessage: "Password is required"
|
|
@@ -21538,21 +21559,30 @@ create().shape({
|
|
|
21538
21559
|
if (!value || typeof value !== "string") return true;
|
|
21539
21560
|
const byteSize = getByteSize(value);
|
|
21540
21561
|
return byteSize <= 72;
|
|
21541
|
-
}).
|
|
21562
|
+
}).test("lowercase", {
|
|
21542
21563
|
message: {
|
|
21543
21564
|
id: "components.Input.error.contain.lowercase",
|
|
21544
21565
|
defaultMessage: "Password must contain at least 1 lowercase letter"
|
|
21545
21566
|
}
|
|
21546
|
-
})
|
|
21567
|
+
}, (value) => {
|
|
21568
|
+
if (!value) return true;
|
|
21569
|
+
return /[a-z]/.test(value);
|
|
21570
|
+
}).test("uppercase", {
|
|
21547
21571
|
message: {
|
|
21548
21572
|
id: "components.Input.error.contain.uppercase",
|
|
21549
21573
|
defaultMessage: "Password must contain at least 1 uppercase letter"
|
|
21550
21574
|
}
|
|
21551
|
-
})
|
|
21575
|
+
}, (value) => {
|
|
21576
|
+
if (!value) return true;
|
|
21577
|
+
return /[A-Z]/.test(value);
|
|
21578
|
+
}).test("number", {
|
|
21552
21579
|
message: {
|
|
21553
21580
|
id: "components.Input.error.contain.number",
|
|
21554
21581
|
defaultMessage: "Password must contain at least 1 number"
|
|
21555
21582
|
}
|
|
21583
|
+
}, (value) => {
|
|
21584
|
+
if (!value) return true;
|
|
21585
|
+
return /\d/.test(value);
|
|
21556
21586
|
}).required({
|
|
21557
21587
|
id: errorsTrads.required.id,
|
|
21558
21588
|
defaultMessage: "Password is required"
|
|
@@ -21612,7 +21642,7 @@ const MainSubNav = styled.styled(designSystem.SubNav)`
|
|
|
21612
21642
|
z-index: 2;
|
|
21613
21643
|
|
|
21614
21644
|
${({ theme }) => theme.breakpoints.medium} {
|
|
21615
|
-
width:
|
|
21645
|
+
width: ${WIDTH_SIDE_NAVIGATION};
|
|
21616
21646
|
position: sticky;
|
|
21617
21647
|
top: 0;
|
|
21618
21648
|
border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
@@ -21705,12 +21735,28 @@ styled.styled(designSystem.Box)`
|
|
|
21705
21735
|
}
|
|
21706
21736
|
`;
|
|
21707
21737
|
styled.styled(designSystem.Badge)`
|
|
21738
|
+
width: 100%;
|
|
21708
21739
|
background: linear-gradient(
|
|
21709
21740
|
90deg,
|
|
21710
21741
|
${({ theme }) => theme.colors.primary600} 0%,
|
|
21711
21742
|
${({ theme }) => theme.colors.alternative600} 121.48%
|
|
21712
21743
|
);
|
|
21713
|
-
padding:
|
|
21744
|
+
padding: 1.1rem 1rem;
|
|
21745
|
+
|
|
21746
|
+
${({ theme }) => theme.breakpoints.small} {
|
|
21747
|
+
padding: 1.2rem 1rem;
|
|
21748
|
+
}
|
|
21749
|
+
${({ theme }) => theme.breakpoints.medium} {
|
|
21750
|
+
padding: 0.4rem 1rem;
|
|
21751
|
+
}
|
|
21752
|
+
`;
|
|
21753
|
+
styled.styled(designSystem.Typography)`
|
|
21754
|
+
font-size: 1.2rem;
|
|
21755
|
+
|
|
21756
|
+
${({ theme }) => theme.breakpoints.small} {
|
|
21757
|
+
font-size: 1.4rem;
|
|
21758
|
+
line-height: 1.6rem;
|
|
21759
|
+
}
|
|
21714
21760
|
`;
|
|
21715
21761
|
const useFetchClient = () => {
|
|
21716
21762
|
const controller = React__namespace.useRef(null);
|
|
@@ -31179,7 +31225,7 @@ const Settings = () => {
|
|
|
31179
31225
|
const { formatMessage } = reactIntl.useIntl();
|
|
31180
31226
|
const [activeView, setActiveView] = React.useState("configure");
|
|
31181
31227
|
const titleId = `${index.PLUGIN_ID}-settings-title`;
|
|
31182
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
|
31228
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { labelledBy: titleId, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 8, background: "neutral100", children: [
|
|
31183
31229
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: titleId, variant: "alpha", as: "h1", children: formatMessage({
|
|
31184
31230
|
id: `${index.PLUGIN_ID}.settings.section`,
|
|
31185
31231
|
defaultMessage: "Advanced Ecommerce"
|
|
@@ -31248,6 +31294,6 @@ const Settings = () => {
|
|
|
31248
31294
|
activeView === "smtp" && /* @__PURE__ */ jsxRuntime.jsx(SmtpContent, {}),
|
|
31249
31295
|
activeView === "api-collections" && /* @__PURE__ */ jsxRuntime.jsx(ApiCollectionsContent, {})
|
|
31250
31296
|
] })
|
|
31251
|
-
] }) })
|
|
31297
|
+
] }) });
|
|
31252
31298
|
};
|
|
31253
31299
|
exports.default = Settings;
|
|
@@ -385,11 +385,13 @@ const en = {
|
|
|
385
385
|
"webbycommerce.settings.apiCollections.products.getAttributes.title": "List Product Attributes",
|
|
386
386
|
"webbycommerce.settings.apiCollections.products.getAttributes.summary": "Get all product attributes with optional filtering.",
|
|
387
387
|
"webbycommerce.settings.apiCollections.cart.applyCoupon.title": "Apply Coupon to Cart",
|
|
388
|
-
"webbycommerce.settings.apiCollections.cart.applyCoupon.summary": "Apply a discount coupon to the authenticated user's cart.",
|
|
388
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.summary": "Apply a discount coupon to the authenticated user's cart. Validates coupon code, expiry, usage limits, and minimum order amount.",
|
|
389
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.auth": "Auth: requires JWT token (Authorization: Bearer <token>) and ecommerce permission enabled.",
|
|
389
390
|
"webbycommerce.settings.apiCollections.cart.removeCoupon.title": "Remove Coupon from Cart",
|
|
390
|
-
"webbycommerce.settings.apiCollections.cart.removeCoupon.summary": "Remove any applied coupon from the authenticated user's cart.",
|
|
391
|
+
"webbycommerce.settings.apiCollections.cart.removeCoupon.summary": "Remove any applied coupon from the authenticated user's cart and recalculate totals.",
|
|
392
|
+
"webbycommerce.settings.apiCollections.cart.removeCoupon.auth": "Auth: requires JWT token (Authorization: Bearer <token>) and ecommerce permission enabled.",
|
|
391
393
|
"webbycommerce.settings.apiCollections.cart.getTotals.title": "Get Cart Totals",
|
|
392
|
-
"webbycommerce.settings.apiCollections.cart.getTotals.summary": "Calculate and return the authenticated user's cart totals.",
|
|
394
|
+
"webbycommerce.settings.apiCollections.cart.getTotals.summary": "Calculate and return the authenticated user's cart totals including subtotal, tax, shipping, discounts, and final total.",
|
|
393
395
|
"webbycommerce.settings.apiCollections.wishlist.moveToCart.title": "Move Wishlist Item to Cart",
|
|
394
396
|
"webbycommerce.settings.apiCollections.wishlist.moveToCart.summary": "Move a product from the authenticated user's wishlist to their cart.",
|
|
395
397
|
"webbycommerce.settings.apiCollections.products.getRelated.usage.product": "Replace :id with the actual product ID.",
|
|
@@ -400,11 +402,15 @@ const en = {
|
|
|
400
402
|
"webbycommerce.settings.apiCollections.products.getTags.usage.pagination": "Returns paginated list of product tags.",
|
|
401
403
|
"webbycommerce.settings.apiCollections.products.getAttributes.usage.filter": "Optional query parameters: ?is_variation=true&limit=20&start=0",
|
|
402
404
|
"webbycommerce.settings.apiCollections.products.getAttributes.usage.variation": "Returns product attributes for variations.",
|
|
403
|
-
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.code":
|
|
404
|
-
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.validation": "Validates coupon expiry, usage limits,
|
|
405
|
-
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.totals": "Returns updated cart totals with discount applied.",
|
|
405
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.code": 'Provide valid coupon code in the request body: {"coupon_code": "SAVE10"}.',
|
|
406
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.validation": "Validates coupon expiry date, usage limits, minimum order amount, and active status.",
|
|
407
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.totals": "Returns updated cart totals with discount applied. Discount is calculated based on coupon type (percentage or fixed amount).",
|
|
408
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.errors": "Returns error messages for invalid codes, expired coupons, usage limit exceeded, or minimum order amount not met.",
|
|
409
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.case": "Coupon code lookup is case-insensitive (tries exact match, uppercase, and lowercase).",
|
|
410
|
+
"webbycommerce.settings.apiCollections.cart.applyCoupon.usage.types": "Supports percentage discounts (e.g., 10% off) and fixed amount discounts (e.g., $5 off).",
|
|
406
411
|
"webbycommerce.settings.apiCollections.cart.removeCoupon.usage.active": "Removes any active coupon from the user's cart.",
|
|
407
|
-
"webbycommerce.settings.apiCollections.cart.removeCoupon.usage.reset": "Resets cart totals to original values.",
|
|
412
|
+
"webbycommerce.settings.apiCollections.cart.removeCoupon.usage.reset": "Resets cart totals to original values without discount.",
|
|
413
|
+
"webbycommerce.settings.apiCollections.cart.removeCoupon.usage.response": "Returns updated cart with recalculated totals after coupon removal.",
|
|
408
414
|
"webbycommerce.settings.apiCollections.cart.getTotals.usage.calculate": "Calculates subtotal, tax, shipping, and discounts.",
|
|
409
415
|
"webbycommerce.settings.apiCollections.cart.getTotals.usage.comprehensive": "Returns complete cart totals breakdown.",
|
|
410
416
|
"webbycommerce.settings.apiCollections.wishlist.moveToCart.usage.product": "Replace :id with the actual product ID from wishlist.",
|
|
@@ -497,7 +503,54 @@ const en = {
|
|
|
497
503
|
"webbycommerce.dashboard.quickActions.subtitle": "Common tasks and testing utilities",
|
|
498
504
|
"webbycommerce.dashboard.quickActions.viewUsers": "View Users",
|
|
499
505
|
"webbycommerce.dashboard.quickActions.viewAddresses": "View Addresses",
|
|
500
|
-
"webbycommerce.dashboard.quickActions.apiDocs": "API Documentation"
|
|
506
|
+
"webbycommerce.dashboard.quickActions.apiDocs": "API Documentation",
|
|
507
|
+
"webbycommerce.settings.apiCollections.coupons.title": "Coupon Management",
|
|
508
|
+
"webbycommerce.settings.apiCollections.coupons.summary": "Manage discount coupons for the ecommerce system. Create, update, and track coupon usage.",
|
|
509
|
+
"webbycommerce.settings.apiCollections.coupons.auth": "Auth: public for reading, admin for writing.",
|
|
510
|
+
"webbycommerce.settings.apiCollections.coupons.authAdmin": "Auth: requires JWT token (Authorization: Bearer <token>) and administrator role.",
|
|
511
|
+
"webbycommerce.settings.apiCollections.coupons.getList.title": "Get All Coupons",
|
|
512
|
+
"webbycommerce.settings.apiCollections.coupons.getList.summary": "Retrieve all discount coupons with optional filtering by active status, expiry date, or usage limits.",
|
|
513
|
+
"webbycommerce.settings.apiCollections.coupons.getSingle.title": "Get Single Coupon",
|
|
514
|
+
"webbycommerce.settings.apiCollections.coupons.getSingle.summary": "Retrieve detailed information for a specific coupon by ID or code.",
|
|
515
|
+
"webbycommerce.settings.apiCollections.coupons.create.title": "Create Coupon",
|
|
516
|
+
"webbycommerce.settings.apiCollections.coupons.create.summary": "Create a new discount coupon with code, type (percentage or fixed), value, and validation rules.",
|
|
517
|
+
"webbycommerce.settings.apiCollections.coupons.update.title": "Update Coupon",
|
|
518
|
+
"webbycommerce.settings.apiCollections.coupons.update.summary": "Update an existing coupon's settings, usage limits, expiry date, or active status.",
|
|
519
|
+
"webbycommerce.settings.apiCollections.coupons.delete.title": "Delete Coupon",
|
|
520
|
+
"webbycommerce.settings.apiCollections.coupons.delete.summary": "Delete a coupon from the system. Cannot be deleted if currently applied to active carts.",
|
|
521
|
+
"webbycommerce.settings.apiCollections.coupons.getList.usage.filter": "Optional query parameters: ?is_active=true&expires_after=2024-12-31&limit=20&start=0",
|
|
522
|
+
"webbycommerce.settings.apiCollections.coupons.getList.usage.active": "Filter coupons by active status to show only currently usable coupons.",
|
|
523
|
+
"webbycommerce.settings.apiCollections.coupons.getList.usage.expiry": "Filter coupons by expiry date to find expired or upcoming expirations.",
|
|
524
|
+
"webbycommerce.settings.apiCollections.coupons.getSingle.usage.id": "Replace :id with the actual coupon ID or use code parameter.",
|
|
525
|
+
"webbycommerce.settings.apiCollections.coupons.getSingle.usage.code": "Can also retrieve by coupon code: ?code=SAVE10",
|
|
526
|
+
"webbycommerce.settings.apiCollections.coupons.create.usage.required": "Required fields: code (unique), type (percentage or fixed), value (decimal).",
|
|
527
|
+
"webbycommerce.settings.apiCollections.coupons.create.usage.optional": "Optional fields: description, usage_limit, minimum_order_amount, expires_at, is_active.",
|
|
528
|
+
"webbycommerce.settings.apiCollections.coupons.create.usage.types": "Type 'percentage' applies discount as percentage (e.g., 10 = 10% off). Type 'fixed' applies fixed amount discount (e.g., 5.00 = $5 off).",
|
|
529
|
+
"webbycommerce.settings.apiCollections.coupons.create.usage.unique": "Coupon code must be unique across all coupons.",
|
|
530
|
+
"webbycommerce.settings.apiCollections.coupons.update.usage.fields": "Update any coupon field: code, type, value, description, usage limits, expiry, or active status.",
|
|
531
|
+
"webbycommerce.settings.apiCollections.coupons.update.usage.impact": "Updating active coupons may affect carts that have already applied the coupon.",
|
|
532
|
+
"webbycommerce.settings.apiCollections.coupons.update.usage.usedCount": "used_count field is automatically incremented when coupons are applied to orders.",
|
|
533
|
+
"webbycommerce.settings.apiCollections.coupons.delete.usage.active": "Cannot delete coupons that are currently applied to active carts.",
|
|
534
|
+
"webbycommerce.settings.apiCollections.coupons.delete.usage.impact": "Deleting a coupon will prevent it from being used in future orders.",
|
|
535
|
+
"webbycommerce.coupon.errors.invalid": "Invalid coupon code",
|
|
536
|
+
"webbycommerce.coupon.errors.required": "Coupon code is required",
|
|
537
|
+
"webbycommerce.coupon.errors.inactive": "This coupon is not active",
|
|
538
|
+
"webbycommerce.coupon.errors.expired": "This coupon has expired",
|
|
539
|
+
"webbycommerce.coupon.errors.usageLimit": "This coupon has reached its usage limit",
|
|
540
|
+
"webbycommerce.coupon.errors.minimumOrder": "Minimum order amount of {amount} required for this coupon",
|
|
541
|
+
"webbycommerce.coupon.success.applied": "Coupon applied successfully",
|
|
542
|
+
"webbycommerce.coupon.success.removed": "Coupon removed successfully",
|
|
543
|
+
"webbycommerce.coupon.types.percentage": "Percentage",
|
|
544
|
+
"webbycommerce.coupon.types.fixed": "Fixed Amount",
|
|
545
|
+
"webbycommerce.coupon.fields.code": "Coupon Code",
|
|
546
|
+
"webbycommerce.coupon.fields.type": "Discount Type",
|
|
547
|
+
"webbycommerce.coupon.fields.value": "Discount Value",
|
|
548
|
+
"webbycommerce.coupon.fields.description": "Description",
|
|
549
|
+
"webbycommerce.coupon.fields.usageLimit": "Usage Limit",
|
|
550
|
+
"webbycommerce.coupon.fields.usedCount": "Times Used",
|
|
551
|
+
"webbycommerce.coupon.fields.minimumOrder": "Minimum Order Amount",
|
|
552
|
+
"webbycommerce.coupon.fields.expiresAt": "Expires At",
|
|
553
|
+
"webbycommerce.coupon.fields.isActive": "Active Status"
|
|
501
554
|
};
|
|
502
555
|
export {
|
|
503
556
|
en as default
|