| 1 |
import { useCallback, useEffect, useMemo } from '@wordpress/element' |
| 2 |
import { getSuggestedPlugins } from '@onboarding/api/DataApi' |
| 3 |
import { CheckboxInput } from '@onboarding/components/CheckboxInput' |
| 4 |
import { useFetch } from '@onboarding/hooks/useFetch' |
| 5 |
import { useUserSelectionStore } from '@onboarding/state/UserSelections' |
| 6 |
|
| 7 |
export const fetcher = () => getSuggestedPlugins() |
| 8 |
export const fetchData = () => ({ key: 'plugins' }) |
| 9 |
export const SuggestedPlugins = () => { |
| 10 |
const { data: suggestedPlugins } = useFetch(fetchData, fetcher) |
| 11 |
const { goals, add, toggle, remove } = useUserSelectionStore() |
| 12 |
|
| 13 |
const nothingToRecommend = useMemo(() => { |
| 14 |
if (!goals?.length) return true |
| 15 |
// If no suggested plugins match any of the goals, return false |
| 16 |
return !goals?.find((goal) => { |
| 17 |
return suggestedPlugins?.some((plugin) => |
| 18 |
plugin?.goals?.includes(goal?.slug), |
| 19 |
) |
| 20 |
}) |
| 21 |
}, [goals, suggestedPlugins]) |
| 22 |
|
| 23 |
const hasGoal = useCallback( |
| 24 |
(plugin) => { |
| 25 |
// True if we have no recommendations |
| 26 |
if (nothingToRecommend) return true |
| 27 |
// Otherwise check the goal/suggestion overlap |
| 28 |
const goalSlugs = goals.map((goal) => goal.slug) |
| 29 |
return plugin?.goals.find((goalSlug) => |
| 30 |
goalSlugs.includes(goalSlug), |
| 31 |
) |
| 32 |
}, |
| 33 |
[goals, nothingToRecommend], |
| 34 |
) |
| 35 |
|
| 36 |
useEffect(() => { |
| 37 |
// Clean up first in case they updated their choices |
| 38 |
suggestedPlugins?.forEach((plugin) => remove('plugins', plugin)) |
| 39 |
|
| 40 |
// If nothing to recommend, don't autoselect anything |
| 41 |
if (nothingToRecommend) return |
| 42 |
|
| 43 |
// Select all plugins that match goals on mount |
| 44 |
suggestedPlugins |
| 45 |
?.filter(hasGoal) |
| 46 |
?.forEach((plugin) => add('plugins', plugin)) |
| 47 |
}, [suggestedPlugins, add, nothingToRecommend, hasGoal, remove]) |
| 48 |
|
| 49 |
return ( |
| 50 |
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4"> |
| 51 |
{suggestedPlugins?.filter(hasGoal)?.map((plugin) => ( |
| 52 |
<div key={plugin.id}> |
| 53 |
<CheckboxInput |
| 54 |
label={plugin.name} |
| 55 |
slug={plugin.wordpressSlug} |
| 56 |
description={plugin.description} |
| 57 |
checked={!nothingToRecommend} |
| 58 |
onChange={() => toggle('plugins', plugin)} |
| 59 |
/> |
| 60 |
</div> |
| 61 |
))} |
| 62 |
</div> |
| 63 |
) |
| 64 |
} |
| 65 |
|