PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / workflows / theme / components / SelectThemeVariation.jsx

SelectThemeVariation.jsx in Extendify 3.1.5, at src/Agent/workflows/theme/components/SelectThemeVariation.jsx

134 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useThemeVariations } from '@agent/hooks/useThemeVariations';
2 import { useVariationOverride } from '@agent/hooks/useVariationOverride';
3 import { useChatStore } from '@agent/state/chat';
4 import { useEffect, useMemo, useRef, useState } from '@wordpress/element';
5 import { __ } from '@wordpress/i18n';
6
7 export const SelectThemeVariation = ({ onConfirm, onCancel }) => {
8 const [css, setCss] = useState('');
9 const [selected, setSelected] = useState(null);
10 const [duotoneTheme, setDuotoneTheme] = useState(null);
11 const { undoChange } = useVariationOverride({ css, duotoneTheme });
12
13 const confirmed = useRef(false);
14 useEffect(() => {
15 return () => {
16 if (!confirmed.current) undoChange();
17 };
18 }, []);
19 const { variations, isLoading } = useThemeVariations();
20 const noVariations = !variations || variations.length === 0;
21 const { addMessage, messages } = useChatStore();
22
23 const shuffled = useMemo(
24 () => (variations ? variations.sort(() => Math.random() - 0.5) : []),
25 [variations],
26 );
27
28 const handleConfirm = () => {
29 if (!selected) return;
30 const variation = variations.find((v) => v.title === selected);
31 if (!variation) {
32 // translators: A chat message shown to the user when their selected color variation cannot be applied
33 const content = __(
34 'We were unable to apply your selected colors. Please try again.',
35 'extendify-local',
36 );
37 addMessage('message', { role: 'assistant', content, error: true });
38 onCancel();
39 return;
40 }
41 confirmed.current = true;
42 onConfirm({ data: { variation }, shouldRefreshPage: true });
43 };
44
45 useEffect(() => {
46 if (isLoading || !noVariations) return;
47 const timer = setTimeout(() => onCancel(), 100);
48 // translators: A chat message shown to the user
49 const content = __(
50 'We were unable to find any colors for your theme',
51 'extendify-local',
52 );
53 const last = messages.at(-1)?.details?.content;
54 if (content === last) return () => clearTimeout(timer);
55 addMessage('message', { role: 'assistant', content, error: true });
56 return () => clearTimeout(timer);
57 }, [addMessage, onCancel, noVariations, messages, isLoading]);
58
59 if (isLoading) {
60 return (
61 <div className="min-h-24 p-2 text-center text-sm">
62 {__('Loading available colors...', 'extendify-local')}
63 </div>
64 );
65 }
66
67 if (noVariations) return null;
68
69 return (
70 <div className="mb-4 ms-12 me-2 flex flex-col rounded-lg border border-gray-300 bg-gray-50">
71 <div className="rounded-lg border-b border-gray-300 bg-white">
72 <div className="grid grid-cols-2 gap-2 p-3">
73 {shuffled?.slice(0, 10)?.map(({ title, css, settings }) => (
74 <button
75 key={title}
76 style={{ backgroundColor: getColor(settings, 'background') }}
77 type="button"
78 className={`relative flex w-full items-center justify-center overflow-hidden rounded-lg border border-gray-300 bg-none p-2 text-center text-sm ${
79 selected === title ? 'ring ring-design-main ring-wp' : ''
80 }`}
81 onClick={() => {
82 setSelected(title);
83 setCss(css);
84 setDuotoneTheme(settings?.color?.duotone?.theme);
85 }}
86 >
87 <div className="flex max-w-fit items-center justify-center -space-x-4 rounded-lg rtl:space-x-reverse">
88 {getColors(settings)?.map((color, i) => (
89 <div
90 key={title + color + i}
91 style={{ backgroundColor: color }}
92 className="size-6 shrink-0 overflow-visible rounded-full border border-white md:size-7"
93 ></div>
94 ))}
95 </div>
96 </button>
97 ))}
98 </div>
99 </div>
100 <div className="flex justify-start gap-2 p-3">
101 <button
102 type="button"
103 className="w-full rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
104 onClick={onCancel}
105 >
106 {__('Cancel', 'extendify-local')}
107 </button>
108 <button
109 type="button"
110 className="w-full rounded-sm border border-design-main bg-design-main p-2 text-sm text-white"
111 disabled={!selected}
112 onClick={handleConfirm}
113 >
114 {__('Save', 'extendify-local')}
115 </button>
116 </div>
117 </div>
118 );
119 };
120
121 const getColor = (settings, colorName) => {
122 return settings?.color?.palette?.theme.find((item) => item.slug === colorName)
123 ?.color;
124 };
125
126 const getColors = (settings) => {
127 return settings?.color?.palette?.theme
128 ?.filter((item) => item.slug !== 'background')
129 ?.reduce((acc, item) => {
130 acc.push(item.color);
131 return acc;
132 }, []);
133 };
134