PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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.2.1, at src/Agent/workflows/theme/components/SelectSiteVibes.jsx

138 lines 4.5 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 }) => {
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 || !noVibes) return;
41 const timer = setTimeout(() => onCancel(), 100);
42 // translators: "site style" refers to the structural aesthetic style for the site.
43 const content = __(
44 'We were unable to find any website style for your theme.',
45 'extendify-local',
46 );
47 const last = messages.at(-1)?.details?.content;
48 if (content === last) return () => clearTimeout(timer);
49 addMessage('message', { role: 'assistant', content, error: true });
50
51 return () => clearTimeout(timer);
52 }, [addMessage, onCancel, noVibes, messages, isLoading]);
53
54 if (isLoading) {
55 return (
56 <div className="min-h-24 p-2 text-center text-sm">
57 {
58 // translators: "site style" refers to the structural aesthetic style for the site.
59 __('Loading website style options...', 'extendify-local')
60 }
61 </div>
62 );
63 }
64
65 if (noVibes) return null;
66
67 return (
68 <div className="mb-4 ms-2 me-2 flex flex-col rounded-lg border border-gray-300 bg-gray-50">
69 <div className="rounded-lg border-b border-gray-400 bg-white">
70 <div className="grid gap-3 p-4 grid-cols-2">
71 {shuffled?.slice(0, 12).map(({ slug }, index) => (
72 <Fragment key={slug}>
73 <style>
74 {styles[slug]
75 ?.replaceAll(':root', '.ext-vibe-container')
76 ?.replaceAll(
77 'is-style-ext-preset--',
78 'preview-is-style-ext-preset--',
79 )}
80 </style>
81 <button
82 aria-label={sprintf(
83 __('Style %s', 'extendify-local'),
84 index + 1,
85 )}
86 aria-pressed={selected === slug}
87 type="button"
88 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 ${
89 selected === slug ? 'ring-2 ring-design-main' : ''
90 }`}
91 onClick={() => setSelected(slug)}
92 >
93 <div
94 className={`wp-block-group w-full h-full preview-is-style-ext-preset--group--${slug}--section has-background-background-color has-background p-4`}
95 >
96 <div
97 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`}
98 >
99 <img
100 src="https://images.extendify-cdn.com/agents/style-selector-preview.jpg"
101 alt={sprintf(
102 __('Style %s', 'extendify-local'),
103 index + 1,
104 )}
105 draggable="false"
106 loading="lazy"
107 width={96}
108 height={96}
109 className="w-full h-full object-cover pointer-events-none"
110 />
111 </div>
112 </div>
113 </button>
114 </Fragment>
115 ))}
116 </div>
117 </div>
118 <div className="flex justify-start gap-2 p-3">
119 <button
120 type="button"
121 className="w-full rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
122 onClick={onCancel}
123 >
124 {__('Cancel', 'extendify-local')}
125 </button>
126 <button
127 type="button"
128 className="w-full rounded-sm border border-design-main bg-design-main p-2 text-sm text-white"
129 disabled={!selected}
130 onClick={handleConfirm}
131 >
132 {__('Save', 'extendify-local')}
133 </button>
134 </div>
135 </div>
136 );
137 };
138