PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.1.4
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.1.4
3.1.4 3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 93 releases
ultimate-store-kit / src / admin / pages / OtherSettings.js

OtherSettings.js in Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder 3.1.4, at src/admin/pages/OtherSettings.js

248 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useState } from '@wordpress/element';
2 import { __ } from '@wordpress/i18n';
3 import { applyFilters } from '@wordpress/hooks';
4 import ProPromo from '../components/ProPromo';
5 import { btnLg, btnPrimary, fieldControl, fieldLabel, proBadge, Toggle } from '../tw';
6
7 const OtherSettings = ({ widgets, section, settings, onSave, saving, isPro, activeGroup }) => {
8 const [localSettings, setLocalSettings] = useState(() => {
9 const initial = {};
10 widgets.forEach((w) => {
11 if (w.type === 'start_group' || w.type === 'end_group') return;
12 if (w.type === 'checkbox') {
13 initial[w.name] =
14 settings[w.name] !== undefined
15 ? settings[w.name]
16 : w.default || 'off';
17 } else if (w.type === 'select' || w.type === 'number' || w.type === 'text') {
18 initial[w.name] =
19 settings[w.name] !== undefined
20 ? settings[w.name]
21 : w.default || '';
22 }
23 });
24 return initial;
25 });
26
27 const handleChange = (name, value) => {
28 setLocalSettings((prev) => ({ ...prev, [name]: value }));
29 };
30
31 const handleSave = () => {
32 onSave(section, localSettings);
33 };
34
35 const renderGroups = () => {
36 const groups = [];
37 let currentGroup = null;
38
39 widgets.forEach((w) => {
40 if (w.type === 'start_group') {
41 currentGroup = { label: w.label, items: [] };
42 return;
43 }
44 if (w.type === 'end_group') {
45 if (currentGroup) {
46 groups.push(currentGroup);
47 currentGroup = null;
48 }
49 return;
50 }
51 if (currentGroup) {
52 currentGroup.items.push(w);
53 } else {
54 if (!groups.length || groups[groups.length - 1].items === undefined) {
55 groups.push({ label: __('General', 'ultimate-store-kit'), items: [] });
56 }
57 groups[groups.length - 1].items.push(w);
58 }
59 });
60
61 return groups;
62 };
63
64 const allGroups = renderGroups();
65 const groups = activeGroup
66 ? allGroups.filter((g) => g.label === activeGroup)
67 : allGroups;
68
69 return (
70 <div>
71 {/* Auto columns: container যত জায়গা দিবে, ততটা সমান-width কলামে সাজাবে */}
72 <div className="grid grid-cols-[repeat(auto-fit,minmax(420px,1fr))] items-start gap-4">
73 {groups.map((group, gi) => (
74 <div
75 key={gi}
76 className="w-full overflow-hidden rounded-usk border border-solid border-gray-100 bg-white"
77 >
78 <h3 className="m-0 border-0 border-b border-solid border-b-gray-200 px-5 py-3.5 text-sm font-bold uppercase tracking-wide text-slate-700">
79 {group.label}
80 </h3>
81 <div className="space-y-5 p-5">
82 {group.items.map((item) => {
83 const isProItem = item.widget_type === 'pro';
84 const dependency = item.dependency || null;
85 const hasMissingDependency =
86 dependency && (!dependency.isInstalled || !dependency.isActive);
87 const isDisabled = (isProItem && !isPro) || hasMissingDependency;
88
89 if (item.type === 'checkbox') {
90 const isOn =
91 !isDisabled &&
92 localSettings[item.name] === 'on';
93 return (
94 <div
95 key={item.name}
96 className="rounded-lg border border-slate-200 bg-white"
97 >
98 <div className="flex items-center justify-between gap-3">
99 <div className={`${fieldLabel} max-w-[70%] flex-wrap`}>
100 <span>
101 {item.label}
102 {hasMissingDependency && dependency?.actionUrl ? (
103 <>
104 {' '}
105 <a
106 href={dependency.actionUrl}
107 target={dependency.actionType === 'install' ? '_blank' : undefined}
108 rel={dependency.actionType === 'install' ? 'noopener noreferrer' : undefined}
109 className="font-semibold text-uks-brand hover:underline"
110 >
111 {dependency.actionLabel}
112 </a>
113 </>
114 ) : null}
115 </span>
116 {isProItem && (
117 <span className={proBadge}>
118 {__('Pro', 'ultimate-store-kit')}
119 </span>
120 )}
121 </div>
122 <Toggle
123 checked={isOn}
124 disabled={isDisabled}
125 onChange={() =>
126 handleChange(
127 item.name,
128 isOn ? 'off' : 'on'
129 )
130 }
131 />
132 </div>
133 {hasMissingDependency && dependency?.message && (
134 <div className="mt-2 text-[13px] leading-relaxed text-slate-500">
135 {dependency.message}
136 </div>
137 )}
138 </div>
139 );
140 }
141
142 if (item.type === 'select') {
143 return (
144 <div
145 key={item.name}
146 className="rounded-lg border border-slate-200 bg-white"
147 >
148 <label className={fieldLabel}>
149 {item.label}
150 {isProItem && (
151 <span className={`${proBadge} ml-2 align-middle`}>
152 {__('Pro', 'ultimate-store-kit')}
153 </span>
154 )}
155 </label>
156 <select
157 className={`${fieldControl} mt-2 block w-full`}
158 value={
159 localSettings[item.name] || ''
160 }
161 onChange={(e) =>
162 handleChange(
163 item.name,
164 e.target.value
165 )
166 }
167 disabled={isDisabled}
168 >
169 {item.options &&
170 Object.entries(
171 item.options
172 ).map(([val, lbl]) => (
173 <option
174 key={val}
175 value={val}
176 >
177 {lbl}
178 </option>
179 ))}
180 </select>
181 </div>
182 );
183 }
184
185 if (
186 item.type === 'number' ||
187 item.type === 'text'
188 ) {
189 return (
190 <div
191 key={item.name}
192 className="rounded-lg border border-slate-200 bg-white"
193 >
194 <label className={fieldLabel}>
195 {item.label}
196 {isProItem && (
197 <span className={`${proBadge} ml-2 align-middle`}>
198 {__('Pro', 'ultimate-store-kit')}
199 </span>
200 )}
201 </label>
202 <input
203 type={item.type}
204 className={`${fieldControl} mt-2 block w-full`}
205 value={
206 localSettings[item.name] || ''
207 }
208 onChange={(e) =>
209 handleChange(
210 item.name,
211 e.target.value
212 )
213 }
214 disabled={isDisabled}
215 />
216 </div>
217 );
218 }
219
220 return null;
221 })}
222 </div>
223 </div>
224 ))}
225 {!isPro && !activeGroup && <ProPromo />}
226 {(() => {
227 const SettingsExtra = applyFilters('usk.admin.settingsExtra', null);
228 return SettingsExtra ? <SettingsExtra activeGroup={activeGroup} /> : null;
229 })()}
230 </div>
231 <div className="mt-6 flex justify-end pt-4">
232 <button
233 type="button"
234 className={`${btnLg} ${btnPrimary}`}
235 onClick={handleSave}
236 disabled={saving}
237 >
238 {saving
239 ? __('Saving...', 'ultimate-store-kit')
240 : __('Save Changes', 'ultimate-store-kit')}
241 </button>
242 </div>
243 </div>
244 );
245 };
246
247 export default OtherSettings;
248