strapi-plugin-payone-provider 1.0.1
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 +571 -0
- package/admin/src/components/Initializer/index.js +16 -0
- package/admin/src/components/PluginIcon/index.js +6 -0
- package/admin/src/index.js +37 -0
- package/admin/src/pages/App/components/ConfigurationPanel.js +265 -0
- package/admin/src/pages/App/components/HistoryPanel.js +298 -0
- package/admin/src/pages/App/components/PaymentActionsPanel.js +333 -0
- package/admin/src/pages/App/components/StatusBadge.js +22 -0
- package/admin/src/pages/App/components/TransactionHistoryItem.js +374 -0
- package/admin/src/pages/App/components/icons/BankIcon.js +10 -0
- package/admin/src/pages/App/components/icons/ChevronDownIcon.js +9 -0
- package/admin/src/pages/App/components/icons/ChevronUpIcon.js +9 -0
- package/admin/src/pages/App/components/icons/CreditCardIcon.js +9 -0
- package/admin/src/pages/App/components/icons/ErrorIcon.js +10 -0
- package/admin/src/pages/App/components/icons/InfoIcon.js +9 -0
- package/admin/src/pages/App/components/icons/PaymentIcon.js +10 -0
- package/admin/src/pages/App/components/icons/PendingIcon.js +9 -0
- package/admin/src/pages/App/components/icons/PersonIcon.js +9 -0
- package/admin/src/pages/App/components/icons/SuccessIcon.js +9 -0
- package/admin/src/pages/App/components/icons/WalletIcon.js +9 -0
- package/admin/src/pages/App/components/icons/index.js +11 -0
- package/admin/src/pages/App/index.js +483 -0
- package/admin/src/pages/utils/api.js +75 -0
- package/admin/src/pages/utils/formatTransactionData.js +16 -0
- package/admin/src/pages/utils/paymentUtils.js +528 -0
- package/admin/src/pluginId.js +5 -0
- package/package.json +43 -0
- package/server/bootstrap.js +26 -0
- package/server/config/index.js +42 -0
- package/server/controllers/index.js +7 -0
- package/server/controllers/payone.js +134 -0
- package/server/destroy.js +5 -0
- package/server/index.js +21 -0
- package/server/policies/index.js +6 -0
- package/server/policies/isAuth.js +23 -0
- package/server/policies/isSuperAdmin.js +18 -0
- package/server/register.js +5 -0
- package/server/routes/index.js +124 -0
- package/server/services/index.js +7 -0
- package/server/services/payone.js +679 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +3 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
CardBody,
|
|
7
|
+
Flex,
|
|
8
|
+
Stack,
|
|
9
|
+
Typography,
|
|
10
|
+
TextInput,
|
|
11
|
+
Select,
|
|
12
|
+
Option,
|
|
13
|
+
Alert
|
|
14
|
+
} from "@strapi/design-system";
|
|
15
|
+
import { Play } from "@strapi/icons";
|
|
16
|
+
|
|
17
|
+
const ConfigurationPanel = ({
|
|
18
|
+
settings,
|
|
19
|
+
isSaving,
|
|
20
|
+
isTesting,
|
|
21
|
+
testResult,
|
|
22
|
+
onSave,
|
|
23
|
+
onTestConnection,
|
|
24
|
+
onInputChange
|
|
25
|
+
}) => {
|
|
26
|
+
return (
|
|
27
|
+
<Box
|
|
28
|
+
hasRadius
|
|
29
|
+
shadow="filterShadow"
|
|
30
|
+
paddingTop={8}
|
|
31
|
+
paddingBottom={8}
|
|
32
|
+
paddingLeft={8}
|
|
33
|
+
paddingRight={8}
|
|
34
|
+
style={{
|
|
35
|
+
borderRadius: "12px",
|
|
36
|
+
boxShadow: "0 4px 20px rgba(0, 0, 0, 0.08)",
|
|
37
|
+
border: "1px solid #f6f6f9"
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Flex direction="column" alignItems="stretch" gap={8}>
|
|
41
|
+
<Box>
|
|
42
|
+
<Typography variant="beta" as="h2" fontWeight="bold">
|
|
43
|
+
Payone API Configuration
|
|
44
|
+
</Typography>
|
|
45
|
+
<Typography variant="pi" marginTop={2}>
|
|
46
|
+
Configure your Payone payment gateway settings
|
|
47
|
+
</Typography>
|
|
48
|
+
</Box>
|
|
49
|
+
|
|
50
|
+
<Box>
|
|
51
|
+
<Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
|
|
52
|
+
<CardBody padding={6}>
|
|
53
|
+
<Stack spacing={6}>
|
|
54
|
+
<Flex gap={4} wrap="wrap">
|
|
55
|
+
<TextInput
|
|
56
|
+
label="Account ID (aid)"
|
|
57
|
+
name="aid"
|
|
58
|
+
value={settings.aid || ""}
|
|
59
|
+
onChange={(e) => onInputChange("aid", e.target.value)}
|
|
60
|
+
required
|
|
61
|
+
hint="Your Payone account ID"
|
|
62
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
63
|
+
/>
|
|
64
|
+
|
|
65
|
+
<TextInput
|
|
66
|
+
label="Portal ID"
|
|
67
|
+
name="portalid"
|
|
68
|
+
value={settings.portalid || ""}
|
|
69
|
+
onChange={(e) => onInputChange("portalid", e.target.value)}
|
|
70
|
+
required
|
|
71
|
+
hint="Your Payone portal ID"
|
|
72
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
73
|
+
/>
|
|
74
|
+
</Flex>
|
|
75
|
+
|
|
76
|
+
<Flex gap={4} wrap="wrap">
|
|
77
|
+
<TextInput
|
|
78
|
+
label="Merchant ID (mid)"
|
|
79
|
+
name="mid"
|
|
80
|
+
value={settings.mid || ""}
|
|
81
|
+
onChange={(e) => onInputChange("mid", e.target.value)}
|
|
82
|
+
required
|
|
83
|
+
hint="Your Payone merchant ID"
|
|
84
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
85
|
+
/>
|
|
86
|
+
|
|
87
|
+
<TextInput
|
|
88
|
+
label="Portal Key"
|
|
89
|
+
name="key"
|
|
90
|
+
type="password"
|
|
91
|
+
value={settings.key || ""}
|
|
92
|
+
onChange={(e) => onInputChange("key", e.target.value)}
|
|
93
|
+
required
|
|
94
|
+
hint="Your Payone portal key (will be encrypted)"
|
|
95
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
96
|
+
/>
|
|
97
|
+
</Flex>
|
|
98
|
+
|
|
99
|
+
<Flex gap={4} wrap="wrap">
|
|
100
|
+
<Select
|
|
101
|
+
label="Mode"
|
|
102
|
+
name="mode"
|
|
103
|
+
value={settings.mode || "test"}
|
|
104
|
+
onChange={(value) => onInputChange("mode", value)}
|
|
105
|
+
hint="Select the API mode"
|
|
106
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
107
|
+
>
|
|
108
|
+
<Option value="test">Test Environment</Option>
|
|
109
|
+
<Option value="live">Live Environment</Option>
|
|
110
|
+
</Select>
|
|
111
|
+
|
|
112
|
+
<TextInput
|
|
113
|
+
label="API Version"
|
|
114
|
+
name="api_version"
|
|
115
|
+
value={settings.api_version || "3.10"}
|
|
116
|
+
onChange={(e) =>
|
|
117
|
+
onInputChange("api_version", e.target.value)
|
|
118
|
+
}
|
|
119
|
+
hint="Payone API version"
|
|
120
|
+
style={{ flex: 1, minWidth: "300px" }}
|
|
121
|
+
/>
|
|
122
|
+
</Flex>
|
|
123
|
+
</Stack>
|
|
124
|
+
</CardBody>
|
|
125
|
+
</Card>
|
|
126
|
+
</Box>
|
|
127
|
+
|
|
128
|
+
<Box paddingTop={6}>
|
|
129
|
+
<Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
|
|
130
|
+
<CardBody padding={6}>
|
|
131
|
+
<Stack spacing={6}>
|
|
132
|
+
<Box>
|
|
133
|
+
<Typography
|
|
134
|
+
variant="delta"
|
|
135
|
+
as="h3"
|
|
136
|
+
fontWeight="bold"
|
|
137
|
+
marginBottom={2}
|
|
138
|
+
>
|
|
139
|
+
Test Connection
|
|
140
|
+
</Typography>
|
|
141
|
+
<Typography variant="pi" textColor="neutral600">
|
|
142
|
+
Verify your Payone configuration by testing the API
|
|
143
|
+
connection
|
|
144
|
+
</Typography>
|
|
145
|
+
</Box>
|
|
146
|
+
|
|
147
|
+
<Button
|
|
148
|
+
variant="default"
|
|
149
|
+
onClick={onTestConnection}
|
|
150
|
+
loading={isTesting}
|
|
151
|
+
startIcon={<Play />}
|
|
152
|
+
style={{
|
|
153
|
+
background: "#28a745",
|
|
154
|
+
border: "none",
|
|
155
|
+
color: "white",
|
|
156
|
+
fontWeight: "600",
|
|
157
|
+
borderRadius: "8px"
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
{isTesting ? "Testing Connection..." : "Test Connection"}
|
|
161
|
+
</Button>
|
|
162
|
+
|
|
163
|
+
{testResult && (
|
|
164
|
+
<Alert
|
|
165
|
+
variant={Boolean(testResult.success) ? "success" : "danger"}
|
|
166
|
+
title={
|
|
167
|
+
Boolean(testResult.success)
|
|
168
|
+
? "Connection Successful"
|
|
169
|
+
: "Connection Failed"
|
|
170
|
+
}
|
|
171
|
+
style={{
|
|
172
|
+
borderRadius: "8px",
|
|
173
|
+
border: Boolean(testResult.success)
|
|
174
|
+
? "1px solid #d4edda"
|
|
175
|
+
: "1px solid #f8d7da"
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
178
|
+
<Typography
|
|
179
|
+
variant="pi"
|
|
180
|
+
fontWeight="medium"
|
|
181
|
+
marginBottom={2}
|
|
182
|
+
>
|
|
183
|
+
{testResult.message}
|
|
184
|
+
</Typography>
|
|
185
|
+
{testResult.details && (
|
|
186
|
+
<Box paddingTop={3}>
|
|
187
|
+
{Boolean(testResult.success) ? (
|
|
188
|
+
<Card
|
|
189
|
+
style={{
|
|
190
|
+
border: "1px solid #e9ecef"
|
|
191
|
+
}}
|
|
192
|
+
>
|
|
193
|
+
<CardBody padding={4}>
|
|
194
|
+
<Typography variant="pi">
|
|
195
|
+
<strong>Mode:</strong> {testResult.details.mode}{" "}
|
|
196
|
+
|<strong> AID:</strong> {testResult.details.aid}{" "}
|
|
197
|
+
|<strong> Portal ID:</strong>{" "}
|
|
198
|
+
{testResult.details.portalid} |
|
|
199
|
+
<strong> Merchant ID:</strong>{" "}
|
|
200
|
+
{testResult.details.mid || ""}
|
|
201
|
+
</Typography>
|
|
202
|
+
</CardBody>
|
|
203
|
+
</Card>
|
|
204
|
+
) : (
|
|
205
|
+
<Card
|
|
206
|
+
style={{
|
|
207
|
+
background: "#fff5f5",
|
|
208
|
+
border: "1px solid #fed7d7"
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
<CardBody padding={4}>
|
|
212
|
+
<Stack spacing={2}>
|
|
213
|
+
{testResult.errorcode && (
|
|
214
|
+
<Typography
|
|
215
|
+
variant="pi"
|
|
216
|
+
textColor="neutral600"
|
|
217
|
+
>
|
|
218
|
+
<strong>Error Code:</strong>{" "}
|
|
219
|
+
{testResult.errorcode}
|
|
220
|
+
</Typography>
|
|
221
|
+
)}
|
|
222
|
+
{testResult.details.errorCode && (
|
|
223
|
+
<Typography
|
|
224
|
+
variant="pi"
|
|
225
|
+
textColor="neutral600"
|
|
226
|
+
>
|
|
227
|
+
<strong>Error Code:</strong>{" "}
|
|
228
|
+
{testResult.details.errorCode}
|
|
229
|
+
</Typography>
|
|
230
|
+
)}
|
|
231
|
+
{testResult.details &&
|
|
232
|
+
testResult.details.rawResponse && (
|
|
233
|
+
<Typography
|
|
234
|
+
variant="pi"
|
|
235
|
+
textColor="neutral600"
|
|
236
|
+
>
|
|
237
|
+
<strong>Debug Info:</strong>{" "}
|
|
238
|
+
{testResult.details.rawResponse}
|
|
239
|
+
</Typography>
|
|
240
|
+
)}
|
|
241
|
+
</Stack>
|
|
242
|
+
</CardBody>
|
|
243
|
+
</Card>
|
|
244
|
+
)}
|
|
245
|
+
</Box>
|
|
246
|
+
)}
|
|
247
|
+
</Alert>
|
|
248
|
+
)}
|
|
249
|
+
</Stack>
|
|
250
|
+
</CardBody>
|
|
251
|
+
</Card>
|
|
252
|
+
</Box>
|
|
253
|
+
|
|
254
|
+
<Box paddingTop={4}>
|
|
255
|
+
<Typography variant="sigma" textColor="neutral600">
|
|
256
|
+
Note: These settings are used for all Payone API requests. Make sure
|
|
257
|
+
to use the correct credentials for your selected mode.
|
|
258
|
+
</Typography>
|
|
259
|
+
</Box>
|
|
260
|
+
</Flex>
|
|
261
|
+
</Box>
|
|
262
|
+
);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export default ConfigurationPanel;
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
CardBody,
|
|
7
|
+
Flex,
|
|
8
|
+
Stack,
|
|
9
|
+
Typography,
|
|
10
|
+
TextInput,
|
|
11
|
+
Divider
|
|
12
|
+
} from "@strapi/design-system";
|
|
13
|
+
import { Search } from "@strapi/icons";
|
|
14
|
+
import TransactionHistoryItem from "./TransactionHistoryItem";
|
|
15
|
+
|
|
16
|
+
const HistoryPanel = ({
|
|
17
|
+
filters,
|
|
18
|
+
onFilterChange,
|
|
19
|
+
onFilterApply,
|
|
20
|
+
isLoadingHistory,
|
|
21
|
+
transactionHistory,
|
|
22
|
+
paginatedTransactions,
|
|
23
|
+
currentPage,
|
|
24
|
+
totalPages,
|
|
25
|
+
pageSize,
|
|
26
|
+
onRefresh,
|
|
27
|
+
onPageChange
|
|
28
|
+
}) => {
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Box
|
|
32
|
+
hasRadius
|
|
33
|
+
shadow="filterShadow"
|
|
34
|
+
paddingTop={8}
|
|
35
|
+
paddingBottom={8}
|
|
36
|
+
paddingLeft={8}
|
|
37
|
+
paddingRight={8}
|
|
38
|
+
style={{
|
|
39
|
+
borderRadius: "12px",
|
|
40
|
+
boxShadow: "0 4px 20px rgba(0, 0, 0, 0.08)",
|
|
41
|
+
border: "1px solid #f6f6f9"
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
<Flex direction="column" alignItems="stretch" gap={8}>
|
|
45
|
+
<Typography variant="beta" as="h2" marginBottom={2}>
|
|
46
|
+
Transaction Management
|
|
47
|
+
</Typography>
|
|
48
|
+
{/* Filters */}
|
|
49
|
+
<Box>
|
|
50
|
+
<Box marginBottom={4}>
|
|
51
|
+
<Typography variant="delta" as="h3" fontWeight="bold">
|
|
52
|
+
Transaction Filters
|
|
53
|
+
</Typography>
|
|
54
|
+
<Typography variant="pi" textColor="neutral600" marginTop={2}>
|
|
55
|
+
Filter transactions by status, type, date range, and more
|
|
56
|
+
</Typography>
|
|
57
|
+
</Box>
|
|
58
|
+
<Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
|
|
59
|
+
<CardBody padding={6}>
|
|
60
|
+
<Stack spacing={4}>
|
|
61
|
+
<Flex gap={4} wrap="wrap" alignItems="center">
|
|
62
|
+
<TextInput
|
|
63
|
+
label="Status"
|
|
64
|
+
name="status"
|
|
65
|
+
value={filters.status}
|
|
66
|
+
onChange={(e) => onFilterChange("status", e.target.value)}
|
|
67
|
+
placeholder="APPROVED, ERROR, etc."
|
|
68
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
69
|
+
/>
|
|
70
|
+
<TextInput
|
|
71
|
+
label="Request Type"
|
|
72
|
+
name="request_type"
|
|
73
|
+
value={filters.request_type}
|
|
74
|
+
onChange={(e) =>
|
|
75
|
+
onFilterChange("request_type", e.target.value)
|
|
76
|
+
}
|
|
77
|
+
placeholder="preauthorization, authorization, etc."
|
|
78
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
79
|
+
/>
|
|
80
|
+
<TextInput
|
|
81
|
+
label="Transaction ID"
|
|
82
|
+
name="txid"
|
|
83
|
+
value={filters.txid}
|
|
84
|
+
onChange={(e) => onFilterChange("txid", e.target.value)}
|
|
85
|
+
placeholder="Enter TxId"
|
|
86
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
87
|
+
/>
|
|
88
|
+
<TextInput
|
|
89
|
+
label="Reference"
|
|
90
|
+
name="reference"
|
|
91
|
+
value={filters.reference}
|
|
92
|
+
onChange={(e) =>
|
|
93
|
+
onFilterChange("reference", e.target.value)
|
|
94
|
+
}
|
|
95
|
+
placeholder="Enter reference"
|
|
96
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
97
|
+
/>
|
|
98
|
+
<TextInput
|
|
99
|
+
label="Date From"
|
|
100
|
+
name="date_from"
|
|
101
|
+
value={filters.date_from}
|
|
102
|
+
onChange={(e) =>
|
|
103
|
+
onFilterChange("date_from", e.target.value)
|
|
104
|
+
}
|
|
105
|
+
placeholder="YYYY-MM-DD"
|
|
106
|
+
type="date"
|
|
107
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
108
|
+
/>
|
|
109
|
+
<TextInput
|
|
110
|
+
label="Date To"
|
|
111
|
+
name="date_to"
|
|
112
|
+
value={filters.date_to}
|
|
113
|
+
onChange={(e) => onFilterChange("date_to", e.target.value)}
|
|
114
|
+
placeholder="YYYY-MM-DD"
|
|
115
|
+
type="date"
|
|
116
|
+
style={{ flex: 1, minWidth: "200px" }}
|
|
117
|
+
/>
|
|
118
|
+
<Button
|
|
119
|
+
variant="default"
|
|
120
|
+
onClick={onFilterApply}
|
|
121
|
+
loading={isLoadingHistory}
|
|
122
|
+
startIcon={<Search />}
|
|
123
|
+
>
|
|
124
|
+
Apply Filters
|
|
125
|
+
</Button>
|
|
126
|
+
</Flex>
|
|
127
|
+
</Stack>
|
|
128
|
+
</CardBody>
|
|
129
|
+
</Card>
|
|
130
|
+
</Box>
|
|
131
|
+
|
|
132
|
+
<Divider />
|
|
133
|
+
|
|
134
|
+
{/* Transaction History */}
|
|
135
|
+
<Box>
|
|
136
|
+
<Box marginBottom={6}>
|
|
137
|
+
<Flex
|
|
138
|
+
justifyContent="space-between"
|
|
139
|
+
alignItems="center"
|
|
140
|
+
marginBottom={4}
|
|
141
|
+
>
|
|
142
|
+
<Box>
|
|
143
|
+
<Typography variant="delta" as="h3" fontWeight="bold">
|
|
144
|
+
Transaction History
|
|
145
|
+
</Typography>
|
|
146
|
+
<Typography variant="pi" textColor="neutral600" marginTop={2}>
|
|
147
|
+
{transactionHistory.length} total transactions •{" "}
|
|
148
|
+
{paginatedTransactions.length} on page {currentPage} of{" "}
|
|
149
|
+
{totalPages}
|
|
150
|
+
</Typography>
|
|
151
|
+
</Box>
|
|
152
|
+
<Button
|
|
153
|
+
variant="default"
|
|
154
|
+
onClick={onRefresh}
|
|
155
|
+
loading={isLoadingHistory}
|
|
156
|
+
startIcon={<Search />}
|
|
157
|
+
size="S"
|
|
158
|
+
style={{
|
|
159
|
+
background: "#28a745",
|
|
160
|
+
border: "none",
|
|
161
|
+
color: "white",
|
|
162
|
+
fontWeight: "600",
|
|
163
|
+
borderRadius: "8px"
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
166
|
+
Refresh
|
|
167
|
+
</Button>
|
|
168
|
+
</Flex>
|
|
169
|
+
</Box>
|
|
170
|
+
|
|
171
|
+
{isLoadingHistory ? (
|
|
172
|
+
<Box padding={4} textAlign="center">
|
|
173
|
+
<Typography>Loading transactions...</Typography>
|
|
174
|
+
</Box>
|
|
175
|
+
) : transactionHistory.length === 0 ? (
|
|
176
|
+
<Box padding={4} textAlign="center">
|
|
177
|
+
<Typography textColor="neutral600">
|
|
178
|
+
No transactions found
|
|
179
|
+
</Typography>
|
|
180
|
+
</Box>
|
|
181
|
+
) : (
|
|
182
|
+
<Box>
|
|
183
|
+
{paginatedTransactions.map((transaction) => (
|
|
184
|
+
<TransactionHistoryItem
|
|
185
|
+
key={transaction.id}
|
|
186
|
+
transaction={transaction}
|
|
187
|
+
/>
|
|
188
|
+
))}
|
|
189
|
+
|
|
190
|
+
{/* Pagination */}
|
|
191
|
+
<Box paddingTop={6} paddingBottom={4}>
|
|
192
|
+
<Card
|
|
193
|
+
style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}
|
|
194
|
+
>
|
|
195
|
+
<CardBody padding={4}>
|
|
196
|
+
<Flex justifyContent="space-between" alignItems="center">
|
|
197
|
+
{transactionHistory.length > pageSize &&
|
|
198
|
+
totalPages > 1 ? (
|
|
199
|
+
<Flex gap={3} alignItems="center">
|
|
200
|
+
<Button
|
|
201
|
+
variant="default"
|
|
202
|
+
size="S"
|
|
203
|
+
onClick={() =>
|
|
204
|
+
onPageChange(Math.max(1, currentPage - 1))
|
|
205
|
+
}
|
|
206
|
+
disabled={currentPage === 1}
|
|
207
|
+
style={{
|
|
208
|
+
background:
|
|
209
|
+
currentPage === 1 ? "#f6f6f9" : "#28a745",
|
|
210
|
+
border: "none",
|
|
211
|
+
color: currentPage === 1 ? "#666687" : "white",
|
|
212
|
+
fontWeight: "600",
|
|
213
|
+
borderRadius: "6px"
|
|
214
|
+
}}
|
|
215
|
+
>
|
|
216
|
+
← Previous
|
|
217
|
+
</Button>
|
|
218
|
+
|
|
219
|
+
<Box
|
|
220
|
+
padding={2}
|
|
221
|
+
background="#f6f6f9"
|
|
222
|
+
borderRadius="6px"
|
|
223
|
+
>
|
|
224
|
+
<Typography
|
|
225
|
+
variant="pi"
|
|
226
|
+
textColor="neutral600"
|
|
227
|
+
fontWeight="bold"
|
|
228
|
+
>
|
|
229
|
+
Page {currentPage} of {totalPages}
|
|
230
|
+
</Typography>
|
|
231
|
+
</Box>
|
|
232
|
+
|
|
233
|
+
<Button
|
|
234
|
+
variant="default"
|
|
235
|
+
size="S"
|
|
236
|
+
onClick={() =>
|
|
237
|
+
onPageChange(
|
|
238
|
+
Math.min(totalPages, currentPage + 1)
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
disabled={currentPage === totalPages}
|
|
242
|
+
style={{
|
|
243
|
+
background:
|
|
244
|
+
currentPage === totalPages
|
|
245
|
+
? "#f6f6f9"
|
|
246
|
+
: "#28a745",
|
|
247
|
+
border: "none",
|
|
248
|
+
color:
|
|
249
|
+
currentPage === totalPages
|
|
250
|
+
? "#666687"
|
|
251
|
+
: "white",
|
|
252
|
+
fontWeight: "600",
|
|
253
|
+
borderRadius: "6px"
|
|
254
|
+
}}
|
|
255
|
+
>
|
|
256
|
+
Next →
|
|
257
|
+
</Button>
|
|
258
|
+
</Flex>
|
|
259
|
+
) : (
|
|
260
|
+
<Typography
|
|
261
|
+
variant="pi"
|
|
262
|
+
textColor="neutral600"
|
|
263
|
+
fontWeight="medium"
|
|
264
|
+
>
|
|
265
|
+
{transactionHistory.length <= pageSize
|
|
266
|
+
? "All transactions shown"
|
|
267
|
+
: "No pagination needed"}
|
|
268
|
+
</Typography>
|
|
269
|
+
)}
|
|
270
|
+
</Flex>
|
|
271
|
+
</CardBody>
|
|
272
|
+
</Card>
|
|
273
|
+
<Typography
|
|
274
|
+
variant="pi"
|
|
275
|
+
textColor="neutral600"
|
|
276
|
+
fontWeight="medium"
|
|
277
|
+
>
|
|
278
|
+
Showing {paginatedTransactions.length} of{" "}
|
|
279
|
+
{transactionHistory.length} transactions
|
|
280
|
+
</Typography>
|
|
281
|
+
</Box>
|
|
282
|
+
</Box>
|
|
283
|
+
)}
|
|
284
|
+
</Box>
|
|
285
|
+
|
|
286
|
+
<Box paddingTop={4}>
|
|
287
|
+
<Typography variant="sigma" textColor="neutral600">
|
|
288
|
+
Note: This shows all Payone transactions processed through this
|
|
289
|
+
plugin. Transactions are automatically logged with detailed
|
|
290
|
+
request/response data.
|
|
291
|
+
</Typography>
|
|
292
|
+
</Box>
|
|
293
|
+
</Flex>
|
|
294
|
+
</Box>
|
|
295
|
+
);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
export default HistoryPanel;
|