Skip to content

Commit

Permalink
Reader Onboarding: Establish Interests Overlay (#95267)
Browse files Browse the repository at this point in the history
* Mostly working tag selection

* Follow and unfollow as the buttons are clicked

* Add translations and update style

* Clean up SCSS

* Clean up typescript
  • Loading branch information
DustyReagan authored Oct 10, 2024
1 parent 1643419 commit d3b3037
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 5 deletions.
174 changes: 169 additions & 5 deletions client/reader/onboarding/interests-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -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 = (
<>
<Button onClick={ onClose } variant="link">
{ __( 'Cancel' ) }
</Button>
<Button onClick={ handleContinue } variant="primary" disabled={ isContinueDisabled }>
{ __( 'Continue' ) }
</Button>
</>
);

return (
isOpen && (
<Modal title="Select Your Interests" onRequestClose={ onClose } isFullScreen>
<p>Interest content here.</p>
<button onClick={ onClose }>Close</button>
<Modal
onRequestClose={ onClose }
isFullScreen
headerActions={ headerActions }
isDismissible={ false }
className="interests-modal"
>
<div className="interests-modal__content">
<h2 className="interests-modal__title">{ __( 'What topics interest you?' ) }</h2>
<p className="interests-modal__subtitle">
{ __( 'Follow at least 3 topics to personalize your Reader feed.' ) }
</p>
{ categories.map( ( category ) => (
<div key={ category.name } className="interests-modal__category">
<h3 className="interests-modal__section-header">{ category.name }</h3>
<div className="interests-modal__topics-list">
{ category.topics.map( ( topic ) => (
<SelectCardCheckbox
key={ topic.name }
onChange={ ( checked ) => handleTopicChange( checked, topic.tag ) }
checked={
Array.isArray( topic.tag )
? topic.tag.every( ( t ) => followedTags.includes( t ) )
: followedTags.includes( topic.tag )
}
>
{ topic.name }
</SelectCardCheckbox>
) ) }
</div>
</div>
) ) }
</div>
</Modal>
)
);
Expand Down
54 changes: 54 additions & 0 deletions client/reader/onboarding/interests-modal/style.scss
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
}

0 comments on commit d3b3037

Please sign in to comment.