PluginProbe
Extendify / 3.1.0
Extendify v3.1.0
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 / SelectSiteVibes.jsx

SelectSiteVibes.jsx in Extendify 3.1.0, at src/Agent/workflows/theme/components/SelectSiteVibes.jsx

143 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useSiteVibesOverride } from '@agent/hooks/useSiteVibesOverride';
2 import { useSiteVibesVariations } from '@agent/hooks/useSiteVibesVariations';
3 import { useChatStore } from '@agent/state/chat';
4 import {
5 Fragment,
6 useEffect,
7 useMemo,
8 useRef,
9 useState,
10 } from '@wordpress/element';
11 import { __, sprintf } from '@wordpress/i18n';
12
13 export const SelectSiteVibes = ({ onConfirm, onCancel, onLoad }) => {
14 const { data, isLoading } = useSiteVibesVariations();
15 const { vibes, css: styles } = data || {};
16 const [selected, setSelected] = useState(null);
17 const css = selected ? styles[selected] : '';
18 const { undoChange } = useSiteVibesOverride({ css, slug: selected });
19 const noVibes = !vibes || vibes.length === 0;
20
21 const confirmed = useRef(false);
22 useEffect(() => {
23 return () => {
24 if (!confirmed.current) undoChange();
25 };
26 }, []);
27 const shuffled = useMemo(
28 () => (vibes ? [...vibes].sort(() => Math.random() - 0.5) : []),
29 [vibes],
30 );
31 const { addMessage, messages } = useChatStore();
32
33 const handleConfirm = () => {
34 if (!selected) return;
35 confirmed.current = true;
36 onConfirm({ data: { selectedVibe: selected }, shouldRefreshPage: true });
37 };
38
39 useEffect(() => {
40 if (isLoading) return;
41 onLoad();
42 }, [isLoading, onLoad]);
43
44 useEffect(() => {
45 if (isLoading || !noVibes) return;
46 const timer = setTimeout(() => onCancel(), 100);
47 // translators: "site style" refers to the structural aesthetic style for the site.
48 const content = __(
49 'We were unable to find any website style for your theme.',
50 'extendify-local',
51 );
52 const last = messages.at(-1)?.details?.content;
53 if (content === last) return () => clearTimeout(timer);
54 addMessage('message', { role: 'assistant', content, error: true });
55
56 return () => clearTimeout(timer);
57 }, [addMessage, onCancel, noVibes, messages, isLoading]);
58
59 if (isLoading) {
60 return (
61 <div className="min-h-24 p-2 text-center text-sm">
62 {
63 // translators: "site style" refers to the structural aesthetic style for the site.
64 __('Loading website style options...', 'extendify-local')
65 }
66 </div>
67 );
68 }
69
70 if (noVibes) return null;
71
72 return (
73 <div className="mb-4 ml-10 mr-2 flex flex-col rounded-lg border border-gray-300 bg-gray-50 rtl:ml-2 rtl:mr-10">
74 <div className="rounded-lg border-b border-gray-400 bg-white">
75 <div className="grid gap-3 p-4 grid-cols-2">
76 {shuffled?.slice(0, 10).map(({ slug }, index) => (
77 <Fragment key={slug}>
78 <style>
79 {styles[slug]
80 ?.replaceAll(':root', '.ext-vibe-container')
81 ?.replaceAll(
82 'is-style-ext-preset--',
83 'preview-is-style-ext-preset--',
84 )}
85 </style>
86 <button
87 aria-label={sprintf(
88 __('Style %s', 'extendify-local'),
89 index + 1,
90 )}
91 aria-pressed={selected === slug}
92 type="button"
93 className={`ext-vibe-container aspect-square relative flex w-full appearance-none items-stretch justify-center overflow-hidden rounded-sm border border-gray-300 bg-none p-0 text-sm shadow-lg focus:outline-none focus:ring-2 focus:ring-design-main focus:ring-offset-1 ${
94 selected === slug ? 'ring-2 ring-design-main' : ''
95 }`}
96 onClick={() => setSelected(slug)}
97 >
98 <div
99 className={`wp-block-group w-full h-full preview-is-style-ext-preset--group--${slug}--section has-background-background-color has-background p-4`}
100 >
101 <div
102 className={`wp-block-group has-tertiary-background-color has-background w-full h-full flex items-center justify-center bg-design-tertiary rtl:space-x-reverse preview-is-style-ext-preset--group--${slug}--item-card-1--align-center p-0`}
103 >
104 <img
105 src="https://images.extendify-cdn.com/agents/style-selector-preview.jpg"
106 alt={sprintf(
107 __('Style %s', 'extendify-local'),
108 index + 1,
109 )}
110 draggable="false"
111 loading="lazy"
112 width={96}
113 height={96}
114 className="w-full h-full object-cover pointer-events-none"
115 />
116 </div>
117 </div>
118 </button>
119 </Fragment>
120 ))}
121 </div>
122 </div>
123 <div className="flex justify-start gap-2 p-3">
124 <button
125 type="button"
126 className="w-full rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
127 onClick={onCancel}
128 >
129 {__('Cancel', 'extendify-local')}
130 </button>
131 <button
132 type="button"
133 className="w-full rounded-sm border border-design-main bg-design-main p-2 text-sm text-white"
134 disabled={!selected}
135 onClick={handleConfirm}
136 >
137 {__('Save', 'extendify-local')}
138 </button>
139 </div>
140 </div>
141 );
142 };
143