PluginProbe
Extendify / 3.0.6
Extendify v3.0.6
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 / Launch / pages / ObjectiveSelection.jsx

ObjectiveSelection.jsx in Extendify 3.0.6, at src/Launch/pages/ObjectiveSelection.jsx

138 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useUserSelectionStore } from '@launch//state/user-selections';
2 import { Title } from '@launch/components/Title';
3 import { PageLayout } from '@launch/layouts/PageLayout';
4 import { pageState } from '@launch/state/factory';
5 import { usePagesStore } from '@launch/state/Pages';
6 import {
7 Blog,
8 Business,
9 ECommerce,
10 LandingPage,
11 OtherSiteTypes,
12 } from '@launch/svg';
13 import { useEffect } from '@wordpress/element';
14 import { __ } from '@wordpress/i18n';
15 import { Icon } from '@wordpress/icons';
16 import classNames from 'classnames';
17
18 export const state = pageState('Website Objective', () => ({
19 ready: false,
20 canSkip: false,
21 useNav: true,
22 onRemove: () => {},
23 }));
24
25 const sections = [
26 {
27 title: __('Business', 'extendify-local'),
28 slug: 'business',
29 icon: <Business />,
30 },
31 {
32 title: __('eCommerce', 'extendify-local'),
33 slug: 'ecommerce',
34 icon: <ECommerce />,
35 },
36 {
37 title: __('Blog', 'extendify-local'),
38 slug: 'blog',
39 icon: <Blog />,
40 },
41 {
42 title: __('Landing Page', 'extendify-local'),
43 slug: 'landing-page',
44 icon: <LandingPage />,
45 },
46 {
47 title: __('Other', 'extendify-local'),
48 slug: 'other',
49 icon: <OtherSiteTypes />,
50 },
51 ];
52
53 export const ObjectiveSelection = () => {
54 const { siteObjective, siteStructure, setSiteObjective, setSiteStructure } =
55 useUserSelectionStore();
56
57 const { nextPage } = usePagesStore();
58
59 const handleClick = (slug) => {
60 setSiteObjective(slug);
61 // Add a small delay before page transition to ensure state updates
62 // (particularly siteStructure) are fully processed and synchronized
63 // before navigating to the next step in the site creation flow.
64 setTimeout(nextPage, 5);
65 };
66
67 useEffect(() => {
68 if (siteObjective === 'landing-page') {
69 setSiteStructure('single-page');
70 }
71 }, [siteObjective, setSiteStructure, siteStructure]);
72
73 useEffect(() => {
74 state.setState({ ready: !!siteObjective });
75 }, [siteObjective]);
76
77 return (
78 <PageLayout>
79 <div className="mx-auto grow overflow-y-auto px-6 py-8 md:p-12 3xl:p-16">
80 <div className="mx-auto flex h-full flex-col justify-center">
81 <Title
82 title={__(
83 'What type of website are you creating?',
84 'extendify-local',
85 )}
86 />
87 <div className="grid grid-cols-2 gap-6 md:grid-cols-3 md:gap-8 lg:grid-cols-5">
88 {sections.map(({ icon, slug, title }) => (
89 <ButtonSelect
90 icon={icon}
91 key={slug}
92 title={title}
93 slug={slug}
94 onClick={() => handleClick(slug)}
95 selected={siteObjective === slug}
96 />
97 ))}
98 </div>
99 </div>
100 </div>
101 </PageLayout>
102 );
103 };
104
105 const ButtonSelect = ({ title, onClick, selected, icon, slug }) => (
106 // biome-ignore lint: keep the radio role until a refactor is done
107 <div
108 data-test={`site-template-type-${slug}`}
109 className={classNames(
110 'relative flex-1 cursor-pointer overflow-hidden rounded-smring-offset-2 ring-offset-white focus-within:outline-hidden focus-within:ring-4 focus-within:ring-design-main focus-within:ring-offset-2 focus-within:ring-offset-white hover:outline-hidden hover:ring-4',
111 {
112 'ring-4 ring-design-main ring-offset-2 ring-offset-white hover:ring-design-main':
113 selected,
114 'hover:ring-gray-300': !selected,
115 },
116 )}
117 role="radio"
118 tabIndex={0}
119 aria-label={__('Press to select', 'extendify-local')}
120 aria-checked={selected}
121 onKeyDown={(e) => {
122 if (!['Enter', 'Space', ' '].includes(e.key)) return;
123 e.preventDefault();
124 onClick();
125 }}
126 onClick={onClick}
127 >
128 <div className="flex h-fit flex-col items-center rounded-sm border border-gray-200">
129 <div className="flex w-full items-center justify-center bg-gray-100 px-8 py-6 md:px-14 md:py-8">
130 <Icon icon={icon} size="48" />
131 </div>
132 <div className="flex items-center justify-center px-px py-3 text-base font-medium text-gray-900">
133 {title}
134 </div>
135 </div>
136 </div>
137 );
138