-
Notifications
You must be signed in to change notification settings - Fork 295
Expand file tree
/
Copy pathPlusList.tsx
More file actions
306 lines (297 loc) · 10.1 KB
/
PlusList.tsx
File metadata and controls
306 lines (297 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
import type { ReactElement } from 'react';
import React from 'react';
import classNames from 'classnames';
import type { WithClassNameProps } from '../utilities';
import type { PlusItem, PlusListItemProps } from './PlusListItem';
import { PlusItemStatus, PlusListItem } from './PlusListItem';
import { LogEvent, TargetType } from '../../lib/log';
import { useLogContext } from '../../contexts/LogContext';
import {
BlockIcon,
BriefIcon,
FolderIcon,
HashtagIcon,
LabelIcon,
LanguageIcon,
ShieldPlusIcon,
SourceIcon,
UserShareIcon,
} from '../icons';
import {
plusShowcaseAdFreeImage,
plusShowcaseBookmarkImage,
plusShowcaseBookmarkVideo,
plusShowcaseCustomFeedsImage,
plusShowcaseCustomFeedsVideo,
plusShowcaseKeywordImage,
plusShowcasePresidentialBriefImage,
plusShowcaseShieldImage,
plusShowcaseShieldVideo,
plusShowcaseSquadImage,
plusShowcaseTeamImage,
plusShowcaseTeamVideo,
plusShowcaseTranslateImage,
} from '../../lib/image';
export const defaultFeatureList: Array<PlusItem> = [
{
label: 'Personalized feed',
status: PlusItemStatus.Ready,
tooltip: `Your go-to place for dev news, tutorials, and updates. Curated just for you, so you never miss what's new.`,
},
{
label: 'Search',
status: PlusItemStatus.Ready,
tooltip: `Find exactly what you're looking for—whether it's answers, trending topics, or the latest tools and resources.`,
},
{
label: 'Squads',
status: PlusItemStatus.Ready,
tooltip: `Join groups of developers who share your interests. Exchange ideas, collaborate, and grow together in a focused space.`,
},
{
label: 'Bookmarks',
status: PlusItemStatus.Ready,
tooltip: `Save posts you want to revisit later. Short on time? Set reading reminders and never lose track of the good stuff.`,
},
{
label: '100+ more features',
status: PlusItemStatus.Ready,
tooltip: `We offer tons of other features for free because we believe high-quality, personalized content should be open for everyone.`,
},
];
export const plusFeatureListControl: Array<PlusItem> = [
{
id: 'public-api',
label: 'Public API access',
status: PlusItemStatus.Ready,
tooltip: `Build custom integrations and access your personalized feed programmatically. Full API access to feeds, bookmarks, search, and more.`,
},
{
id: 'presidential-briefing',
label: 'Unlimited presidential briefings',
status: PlusItemStatus.Ready,
tooltip: `daily.dev scans the latest dev content, filters the noise, and delivers a personalized briefing of what actually matters.`,
icon: <BriefIcon secondary />,
iconClasses: 'bg-overlay-float-mustard text-accent-mustard-default',
modalProps: {
title: 'Unlimited presidential briefings',
description:
'daily.dev scans the latest dev content, filters the noise, and delivers a personalized briefing of what actually matters.',
imageUrl: plusShowcasePresidentialBriefImage,
mediaType: 'image',
},
},
{
id: 'custom feeds',
label: 'Advanced custom feeds',
status: PlusItemStatus.Ready,
tooltip: `Build laser-focused feeds for the tools, languages, and topics you care about. Search less, learn more.`,
icon: <HashtagIcon secondary />,
iconClasses: 'bg-overlay-float-water text-accent-water-default',
modalProps: {
title: 'Advanced custom feeds',
description:
'Build laser-focused feeds for the tools, languages, and topics you care about. Search less, learn more.',
videoUrl: plusShowcaseCustomFeedsVideo,
imageUrl: plusShowcaseCustomFeedsImage,
mediaType: 'video',
},
},
{
id: 'clean titles',
label: 'AI-powered clean titles',
status: PlusItemStatus.Ready,
tooltip: `No more misinformation. AI rewrites titles so you see the real story at a glance and dive in only when relevant.`,
icon: <ShieldPlusIcon secondary />,
iconClasses: 'bg-overlay-float-avocado text-accent-avocado-default',
modalProps: {
title: 'AI-powered clean titles',
description:
'No more misinformation. AI rewrites titles so you see the real story at a glance and dive in only when relevant.',
videoUrl: plusShowcaseShieldVideo,
imageUrl: plusShowcaseShieldImage,
mediaType: 'video',
},
},
{
id: 'bookmark folders',
label: 'Bookmark folders',
status: PlusItemStatus.Ready,
tooltip: `Easily categorize and organize your bookmarked posts into folders so you can find what you need quickly.`,
icon: <FolderIcon secondary />,
iconClasses: 'bg-overlay-float-bun text-accent-bun-default',
modalProps: {
title: 'Bookmark folders',
description:
'Easily categorize and organize your bookmarked posts into folders so you can find what you need quickly.',
videoUrl: plusShowcaseBookmarkVideo,
imageUrl: plusShowcaseBookmarkImage,
mediaType: 'video',
},
},
{
id: 'ad-free',
label: 'Ad-free experience',
status: PlusItemStatus.Ready,
tooltip: `No ads. No clutter. Just pure content. Your feed, distraction-free.`,
icon: <BlockIcon secondary />,
iconClasses: 'bg-overlay-float-ketchup text-accent-ketchup-default',
modalProps: {
title: 'Ad-free experience',
description:
'No ads. No clutter. Just pure content. Your feed, distraction-free.',
imageUrl: plusShowcaseAdFreeImage,
mediaType: 'image',
},
},
{
id: 'auto-translate',
label: 'Auto-translate your feed',
status: PlusItemStatus.Ready,
tooltip: `Translate post titles and summaries into your language for a smoother learning experience.`,
icon: <LanguageIcon secondary />,
iconClasses: 'bg-overlay-float-bacon text-accent-bacon-default',
modalProps: {
title: 'Auto-translate your feed',
description:
'Make your feed more accessible with automatically translated post titles in your preferred language.',
imageUrl: plusShowcaseTranslateImage,
mediaType: 'image',
},
},
{
id: 'keyword filter',
label: 'Keyword filters',
status: PlusItemStatus.Ready,
tooltip: `Mute the buzzwords you're sick of hearing. More signal, less noise.`,
icon: <LabelIcon secondary />,
iconClasses: 'bg-overlay-float-cheese text-accent-cheese-default',
modalProps: {
title: 'Keyword filters',
description:
'Mute the buzzwords you’re sick of hearing. More signal, less noise.',
imageUrl: plusShowcaseKeywordImage,
mediaType: 'image',
},
},
{
id: 'member squad',
label: 'Members-only Squad',
status: PlusItemStatus.Ready,
tooltip: `Join an exclusive community space to connect with other Plus members, share feedback, and get priority support.`,
icon: <SourceIcon secondary />,
iconClasses: 'bg-overlay-float-cabbage text-accent-cabbage-default',
modalProps: {
title: 'Members-only Squad',
description:
'Join an exclusive community space to connect with other Plus members, share feedback, and get priority support.',
imageUrl: plusShowcaseSquadImage,
mediaType: 'image',
},
},
{
id: 'support team',
label: 'Support the team and make us smile',
status: PlusItemStatus.Ready,
tooltip: `By subscribing to Plus, you help us suffer less and build more (well... mostly suffer less).`,
icon: <UserShareIcon secondary />,
iconClasses: 'bg-overlay-float-bacon text-accent-bacon-default',
modalProps: {
title: 'Support the team and make us smile',
description:
'By subscribing to Plus, you help us suffer less and build more (well... mostly suffer less).',
videoUrl: plusShowcaseTeamVideo,
imageUrl: plusShowcaseTeamImage,
mediaType: 'video',
},
},
];
export const plusFeatureList = plusFeatureListControl;
export const plusOrganizationFeatureList: Array<PlusItem> = [
{
label: 'All premium features for every seat',
status: PlusItemStatus.Ready,
tooltip:
'Every team member gets full access to daily.dev Plus—no limitations, no compromises.',
},
{
label: 'Boost engagement with shared learning',
status: PlusItemStatus.Ready,
tooltip:
'Create a culture of growth by discovering and discussing content as a team.',
},
{
label: 'Centralized billing & user management',
status: PlusItemStatus.Ready,
tooltip:
'Manage seats, billing, and team roles from a single dashboard. Simple and scalable.',
},
{
label: 'Get insights on team activity',
status: PlusItemStatus.Ready,
tooltip:
'See what your team is learning, reading, and engaging with—no micromanagement required.',
},
{
label: 'Onboard easily with team invites',
status: PlusItemStatus.Ready,
tooltip:
'Invite teammates in seconds and get them set up with Plus automatically.',
},
{
label: 'Priority support for your team',
status: PlusItemStatus.Ready,
tooltip:
'Get faster responses and dedicated help when your team needs it most.',
},
];
export const briefFeatureList: Array<PlusItem> = [
{
label: 'Unlimited presidential briefings',
status: PlusItemStatus.Ready,
},
{
label: 'Set your preferred schedule',
status: PlusItemStatus.Ready,
},
{
label: 'Choose your delivery method',
status: PlusItemStatus.Ready,
},
{
label: 'Includes all other daily.dev Plus features',
status: PlusItemStatus.Ready,
},
];
interface PlusListProps
extends Omit<PlusListItemProps, 'item'>,
WithClassNameProps {
items?: PlusItem[];
}
export const PlusList = ({
className,
items = plusFeatureList,
...props
}: PlusListProps & WithClassNameProps): ReactElement => {
const { logEvent } = useLogContext();
const handleItemHover = (item: PlusItem) => {
logEvent({
event_name: LogEvent.HoverPlusFeature,
target_id: item.id,
target_type: TargetType.List,
});
};
return (
<ul className={classNames('flex flex-col gap-0.5 py-6', className)}>
{items.map((item) => (
<PlusListItem
key={item.label}
item={item}
typographyProps={item.typographyProps}
onHover={() => handleItemHover(item)}
{...props}
/>
))}
</ul>
);
};