From d3b30376d77a6bd329d3f251ac3b934f9e72e0d6 Mon Sep 17 00:00:00 2001 From: Dusty Reagan Date: Thu, 10 Oct 2024 13:55:56 -0500 Subject: [PATCH] Reader Onboarding: Establish Interests Overlay (#95267) * Mostly working tag selection * Follow and unfollow as the buttons are clicked * Add translations and update style * Clean up SCSS * Clean up typescript --- .../onboarding/interests-modal/index.tsx | 174 +++++++++++++++++- .../onboarding/interests-modal/style.scss | 54 ++++++ 2 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 client/reader/onboarding/interests-modal/style.scss diff --git a/client/reader/onboarding/interests-modal/index.tsx b/client/reader/onboarding/interests-modal/index.tsx index bd3688c49489f..4a1e386b2907d 100644 --- a/client/reader/onboarding/interests-modal/index.tsx +++ b/client/reader/onboarding/interests-modal/index.tsx @@ -1,17 +1,181 @@ -import { Modal } from '@wordpress/components'; -import React from 'react'; +import { SelectCardCheckbox } from '@automattic/onboarding'; +import { Modal, Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import React, { useState, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { requestFollowTag, requestUnfollowTag } from 'calypso/state/reader/tags/items/actions'; +import { getReaderFollowedTags } from 'calypso/state/reader/tags/selectors'; + +import './style.scss'; interface InterestsModalProps { isOpen: boolean; onClose: () => void; } +interface Topic { + name: string; + tag: string; +} + +interface Category { + name: string; + topics: Topic[]; +} + +interface Tag { + slug: string; +} + const InterestsModal: React.FC< InterestsModalProps > = ( { isOpen, onClose } ) => { + const [ followedTags, setFollowedTags ] = useState< string[] >( [] ); + const followedTagsFromState = useSelector( getReaderFollowedTags ); + const dispatch = useDispatch(); + + useEffect( () => { + if ( followedTagsFromState ) { + const initialTags = followedTagsFromState.map( ( tag: Tag ) => tag.slug ); + setFollowedTags( initialTags ); + } + }, [ followedTagsFromState ] ); + + const isContinueDisabled = followedTags.length < 3; + + const handleTopicChange = ( checked: boolean, tag: string ) => { + if ( checked ) { + dispatch( requestFollowTag( tag ) ); + setFollowedTags( ( currentTags ) => [ ...currentTags, tag ] ); + } else { + dispatch( requestUnfollowTag( tag ) ); + setFollowedTags( ( currentTags ) => currentTags.filter( ( t ) => t !== tag ) ); + } + }; + + const handleContinue = () => { + if ( ! isContinueDisabled ) { + onClose(); + } + }; + + const categories: Category[] = [ + { + name: __( 'Lifestyle & Personal Development' ), + topics: [ + { name: __( 'Health' ), tag: 'health' }, + { name: __( 'Personal Finance' ), tag: 'personal-finance' }, + { name: __( 'Food' ), tag: 'food' }, + { name: __( 'Life Hacks' ), tag: 'life-hacks' }, + { name: __( 'Mental Health' ), tag: 'mental-health' }, + { name: __( 'Sleep' ), tag: 'sleep' }, + { name: __( 'Relationships' ), tag: 'relationships' }, + { name: __( 'Parenting' ), tag: 'parenting' }, + { name: __( 'Travel' ), tag: 'travel' }, + ], + }, + { + name: __( 'Technology & Innovation' ), + topics: [ + { name: __( 'Gadgets' ), tag: 'gadgets' }, + { name: __( 'Software' ), tag: 'software' }, + { name: __( 'Tech News' ), tag: 'technology' }, + { name: __( 'Design' ), tag: 'design' }, + { name: __( 'Artificial Intelligence' ), tag: 'artificial-intelligence' }, + { name: __( 'Cybersecurity' ), tag: 'cybersecurity' }, + { name: __( 'Gaming' ), tag: 'gaming' }, + { name: __( 'Crypto' ), tag: 'cryptocurrency' }, + { name: __( 'Science' ), tag: 'science' }, + ], + }, + { + name: __( 'Creative Arts & Entertainment' ), + topics: [ + { name: __( 'Music' ), tag: 'music' }, + { name: __( 'Movies' ), tag: 'movies' }, + { name: __( 'Books' ), tag: 'books' }, + { name: __( 'Art' ), tag: 'art' }, + { name: __( 'Theatre & Performance' ), tag: 'theatre' }, + { name: __( 'Creative Writing' ), tag: 'writing' }, + { name: __( 'Architecture' ), tag: 'architecture' }, + { name: __( 'Photography' ), tag: 'photography' }, + { name: __( 'DIY Projects' ), tag: 'diy' }, + ], + }, + { + name: __( 'Society & Culture' ), + topics: [ + { name: __( 'Education' ), tag: 'education' }, + { name: __( 'Nature' ), tag: 'nature' }, + { name: __( 'Future' ), tag: 'future' }, + { name: __( 'Politics' ), tag: 'politics' }, + { name: __( 'Climate' ), tag: 'climate-change' }, + { name: __( 'History' ), tag: 'history' }, + { name: __( 'Society' ), tag: 'society' }, + { name: __( 'Culture' ), tag: 'culture' }, + { name: __( 'Philosophy' ), tag: 'philosophy' }, + ], + }, + { + name: __( 'Industry' ), + topics: [ + { name: __( 'Business' ), tag: 'business' }, + { name: __( 'Startups' ), tag: 'startups' }, + { name: __( 'Finance' ), tag: 'finance' }, + { name: __( 'Space' ), tag: 'space' }, + { name: __( 'Leadership' ), tag: 'leadership' }, + { name: __( 'Marketing' ), tag: 'marketing' }, + { name: __( 'Remote Work' ), tag: 'remote-work' }, + { name: __( 'SaaS' ), tag: 'saas' }, + { name: __( 'Creator Economy' ), tag: 'creator-economy' }, + ], + }, + ]; + + const headerActions = ( + <> + + + + ); + return ( isOpen && ( - -

Interest content here.

- + +
+

{ __( 'What topics interest you?' ) }

+

+ { __( 'Follow at least 3 topics to personalize your Reader feed.' ) } +

+ { categories.map( ( category ) => ( +
+

{ category.name }

+
+ { category.topics.map( ( topic ) => ( + handleTopicChange( checked, topic.tag ) } + checked={ + Array.isArray( topic.tag ) + ? topic.tag.every( ( t ) => followedTags.includes( t ) ) + : followedTags.includes( topic.tag ) + } + > + { topic.name } + + ) ) } +
+
+ ) ) } +
) ); diff --git a/client/reader/onboarding/interests-modal/style.scss b/client/reader/onboarding/interests-modal/style.scss new file mode 100644 index 0000000000000..8ed15f3fffc19 --- /dev/null +++ b/client/reader/onboarding/interests-modal/style.scss @@ -0,0 +1,54 @@ +@import '@wordpress/base-styles/breakpoints'; +@import '@wordpress/base-styles/mixins'; + +.interests-modal { + &__content { + padding: 24px; + } + + &__title { + font-family: Recoleta, sans-serif; + font-size: 2.75rem; + font-weight: 400; + text-align: center; + } + + &__subtitle { + text-align: center; + } + + &__category { + max-width: 1200px; + margin: 0 auto 32px auto; + } + + &__section-header { + margin-bottom: 16px; + } + + &__topics-list { + display: grid; + gap: 16px; + grid-template-columns: 1fr; + + @include break-small { + grid-template-columns: repeat( 2, 1fr ); + } + + @include break-large { + grid-template-columns: repeat( 3, 1fr ); + } + } + + .components-modal__header { + .components-button { + &.is-link { + margin-right: auto; + } + + &.is-primary { + margin-left: 16px; + } + } + } +}