0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-13 22:41:32 -05:00

Improved recommendations settings design (#18412)

refs https://github.com/TryGhost/Product/issues/3974, https://github.com/TryGhost/Product/issues/3936, https://github.com/TryGhost/Product/issues/3948

- Added dark mode improvements
- Added "Show more" button in "Recommending you" list
- Added "Copy link" button to settings
This commit is contained in:
Djordje Vlaisavljevic 2023-10-02 11:16:21 +01:00 committed by GitHub
parent 01646580e4
commit cb66447747
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 10 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M15.703125 4.21875V1.640625a0.9375 0.9375 0 0 0 -0.9375 -0.9375h-13.125a0.9375 0.9375 0 0 0 -0.9375 0.9375v13.125a0.9375 0.9375 0 0 0 0.9375 0.9375H4.21875" stroke-width="1.5"></path><path stroke="currentColor" stroke-linejoin="round" d="M6.796875 7.734375a0.9375 0.9375 0 0 1 0.9375 -0.9375h13.125a0.9375 0.9375 0 0 1 0.9375 0.9375v13.125a0.9375 0.9375 0 0 1 -0.9375 0.9375h-13.125a0.9375 0.9375 0 0 1 -0.9375 -0.9375v-13.125Z" stroke-width="1.5"></path></svg>

After

Width:  |  Height:  |  Size: 642 B

View file

@ -38,7 +38,7 @@ const Toast: React.FC<ToastProps> = ({
const classNames = clsx(
'z-[90] flex items-start justify-between gap-6 rounded px-4 py-3 text-sm font-medium text-white',
(props?.type === 'success' || props?.type === 'neutral') && 'w-[300px] bg-black',
(props?.type === 'success' || props?.type === 'neutral') && 'w-[300px] bg-black dark:bg-grey-950',
props?.type === 'error' && 'w-[300px] bg-red',
props?.options?.position === 'top-center' && 'w-full max-w-[520px] bg-red',
t.visible ? (props?.options?.position === 'top-center' ? 'animate-toaster-top-in' : 'animate-toaster-in') : 'animate-toaster-out'

View file

@ -59,6 +59,7 @@ const AddRecommendationModalConfirm: React.FC<AddRecommendationModalProps> = ({r
let leftButtonProps = {
label: 'Back',
icon: 'arrow-left',
iconColorClass: 'text-black dark:text-white',
size: 'sm' as const,
onClick: () => {
if (saveState === 'saving') {

View file

@ -1,7 +1,7 @@
import NoValueLabel from '../../../../admin-x-ds/global/NoValueLabel';
import React, {useMemo} from 'react';
import RecommendationIcon from './RecommendationIcon';
import Table from '../../../../admin-x-ds/global/Table';
import Table, {ShowMoreData} from '../../../../admin-x-ds/global/Table';
import TableCell from '../../../../admin-x-ds/global/TableCell';
import TableRow from '../../../../admin-x-ds/global/TableRow';
import {Mention} from '../../../../api/mentions';
@ -12,6 +12,7 @@ interface IncomingRecommendationListProps {
mentions: Mention[],
stats: ReferrerHistoryItem[],
pagination: PaginationData,
showMore?: ShowMoreData,
isLoading: boolean
}
@ -61,9 +62,9 @@ const IncomingRecommendationItem: React.FC<{mention: Mention, stats: ReferrerHis
);
};
const IncomingRecommendationList: React.FC<IncomingRecommendationListProps> = ({mentions, stats, pagination, isLoading}) => {
const IncomingRecommendationList: React.FC<IncomingRecommendationListProps> = ({mentions, stats, pagination, showMore, isLoading}) => {
if (isLoading || mentions.length) {
return <Table isLoading={isLoading} pagination={pagination}>
return <Table isLoading={isLoading} pagination={pagination} showMore={showMore} hintSeparator>
{mentions.map(mention => <IncomingRecommendationItem key={mention.id} mention={mention} stats={stats} />)}
</Table>;
} else {

View file

@ -1,5 +1,5 @@
import NoValueLabel from '../../../../admin-x-ds/global/NoValueLabel';
import React from 'react';
import React, {useState} from 'react';
import RecommendationIcon from './RecommendationIcon';
import Table, {ShowMoreData} from '../../../../admin-x-ds/global/Table';
import TableCell from '../../../../admin-x-ds/global/TableCell';
@ -61,9 +61,6 @@ const RecommendationItem: React.FC<{recommendation: Recommendation}> = ({recomme
);
};
// TODO: Remove if we decide we don't need headers
// const tableHeader = (<><TableHead>Site</TableHead><TableHead>Conversions from you</TableHead></>);
const RecommendationList: React.FC<RecommendationListProps> = ({recommendations, pagination, showMore, isLoading}) => {
const {
siteData
@ -75,8 +72,16 @@ const RecommendationList: React.FC<RecommendationListProps> = ({recommendations,
updateRoute('recommendations/add');
};
const [copied, setCopied] = useState(false);
const copyRecommendationsUrl = () => {
navigator.clipboard.writeText(recommendationsURL);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
if (isLoading || recommendations.length) {
return <Table hint={<span>Shared with new members after signup, or anytime using <Link href={recommendationsURL} target='_blank'>this link</Link></span>} isLoading={isLoading} pagination={pagination} showMore={showMore} hintSeparator>
return <Table hint={<span className='flex items-center gap-1'>Shared with new members after signup, or anytime using <Link href={recommendationsURL} target='_blank'>this link</Link><Button color='clear' hideLabel={true} icon={copied ? 'check-circle' : 'duplicate'} iconColorClass={copied ? 'text-green' : 'text-grey-900'} size='sm' unstyled={true} onClick={copyRecommendationsUrl} /></span>} isLoading={isLoading} pagination={pagination} showMore={showMore} hintSeparator>
{recommendations && recommendations.map(recommendation => <RecommendationItem key={recommendation.id} recommendation={recommendation} />)}
</Table>;
} else {

View file

@ -65,7 +65,7 @@ const RecommendationReasonForm: React.FC<Props<EditOrAddRecommendation | Recomme
<TextArea
clearBg={true}
error={Boolean(errors.reason)}
hint={errors.reason || <>Max. <strong>200</strong> characters. You&apos;ve used <strong className={reasonLengthColor}>{reasonLength}</strong></>}
hint={errors.reason || <>Max: <strong>200</strong> characters. You&#8217;ve used <strong className={reasonLengthColor}>{reasonLength}</strong></>}
rows={3}
title="Short description"
value={formState.reason ?? ''}