File "index.js"
Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/surerank/src/global/components/social-preview/index.js
File size: 8.09 KB
MIME-type: text/x-java
Charset: utf-8
import { __, sprintf } from '@wordpress/i18n';
import { Image, BadgeCheck } from 'lucide-react';
import { Avatar, Text } from '@bsf/force-ui';
import { cn, decodeHtmlEntities } from '@Functions/utils';
import GlobalRemoveButton from '@AdminComponents/global-remove-image-button';
import { renderToString } from '@wordpress/element';
const getDateString = ( type ) => {
const date = new Date();
const month = date.toLocaleString( 'default', { month: 'long' } );
const day = date.getDate();
if ( 'twitter' === type ) {
return `${ month?.slice( 0, 3 ) } ${ day }`;
}
return `${ month } ${ day }`;
};
const ImagePlaceholder = ( { className, ...props } ) => (
<div
className={ cn(
'w-full h-full bg-background-secondary flex items-center justify-center',
className
) }
{ ...props }
>
<Image className="size-6 m-auto" />
</div>
);
const TwitterPreview = ( {
displayName = 'Name',
username = '@username',
timeLabel = '28m',
postText = 'Sample Post Title',
title = __(
'Modern WordPress SEO Plugin Without the Bloat - SureRank',
'surerank'
),
description = '',
imageURL = '',
siteURL = 'surerank.com',
onClickRemove,
hideRemoveButton = true,
forMetaBox = false,
cardType = 'summary_large_image', // 'summary_large_image' or 'summary'
} ) => {
const decodedTitle = decodeHtmlEntities( title );
const decodedDescription = decodeHtmlEntities( description );
const commonProps = {
id: 'x-preview-large',
className: '[#x-preview-large&_*]:font-twitter',
};
const avatar = (
<Avatar
className="flex-shrink-0"
size={ forMetaBox ? 'sm' : 'md' }
variant="primary"
src="https://www.gravatar.com/avatar/?d=mp"
>
User
</Avatar>
);
const userInfo = (
<div className="inline-flex items-center gap-1">
<Text
as="p"
className="m-0"
size={ 16 }
weight={ 500 }
color="secondary"
>
{ displayName }
</Text>
<BadgeCheck
className="size-5 text-white fill-[#1d9bf0]"
aria-label={ __( 'Verified account', 'surerank' ) }
/>
<Text
as="p"
className="m-0"
size={ 16 }
weight={ 400 }
color="secondary"
>
{ username } · { timeLabel }
</Text>
</div>
);
// For large card preview
if ( cardType === 'summary_large_image' ) {
const defaultPostText = sprintf(
/* translators: %s: site URL */
__( 'Check out my page: %s', 'surerank' ),
renderToString(
<Text
className="inline text-[#1d9bf0] m-0 hover:underline"
as="p"
>
{ siteURL.startsWith( 'http' )
? siteURL
: `https://${ siteURL }` }
</Text>
)
);
return (
<div { ...commonProps }>
<div className="p-3 flex items-start gap-3">
{ avatar }
<div className="flex-1">
{ userInfo }
{ postText ? (
<Text
as="p"
className="mt-0.5 mb-0 line-clamp-2"
size={ 14 }
color="secondary"
>
{ postText }
</Text>
) : (
<Text
as="p"
color="secondary"
size={ 14 }
className="mt-0.5 mb-0 line-clamp-2"
dangerouslySetInnerHTML={ {
__html: defaultPostText,
} }
/>
) }
<div className="relative mt-3 rounded-2xl border border-solid border-border-subtle overflow-hidden">
{ imageURL ? (
<div
className={ cn(
'relative w-full h-[16.8125rem]',
forMetaBox && 'h-52'
) }
>
<img
src={ imageURL }
alt="Shared link preview"
className="w-full h-full object-cover"
/>
{ ! hideRemoveButton && (
<GlobalRemoveButton
onClick={ onClickRemove }
/>
) }
</div>
) : (
<div className="h-[16.8125rem]">
<ImagePlaceholder />
</div>
) }
<div className="inline-block w-fit px-2 rounded absolute bottom-3 left-3 right-3 text-xs text-white bg-black/[0.77]">
<Text
as="p"
className="m-0 line-clamp-1 text-inherit"
>
{ decodedTitle }
</Text>
</div>
</div>
<Text
as="p"
color="secondary"
size={ 14 }
weight={ 400 }
className="mt-2 mb-1"
>
{ __( 'From', 'surerank' ) }{ ' ' }
<span className="hover:underline">{ siteURL }</span>
</Text>
</div>
</div>
</div>
);
}
// For summary (small) card preview
return (
<div
id={ commonProps.id }
className={ cn( 'p-3', commonProps.className ) }
>
{ /* Header */ }
<div className="flex gap-3 justify-start items-start">
{ avatar }
<div className="space-y-4">
{ userInfo }
<div className="grid overflow-hidden min-h-[7.75rem] grid-cols-[7.5rem_1fr] rounded-2xl border border-solid border-border-subtle">
{ imageURL ? (
<div className="relative w-full h-full inline-flex">
<img
className="w-full h-full object-cover m-0 max-h-[7.625rem] border-y-0 border-l-0 border-r border-solid border-border-subtle"
src={ imageURL }
alt="thumbnail"
/>
{ ! hideRemoveButton && (
<GlobalRemoveButton
onClick={ onClickRemove }
/>
) }
</div>
) : (
<ImagePlaceholder className="border-y-0 border-l-0 border-r border-solid border-border-subtle" />
) }
<div className="inline-grid items-center justify-start gap-0.5 px-3 py-5">
<p className="m-0 font-normal text-text-secondary leading-4 text-xs">
{ siteURL }
</p>
<div className="w-full overflow-hidden">
<p className="m-0 text-[0.9375rem] font-semibold text-text-primary whitespace-nowrap leading-5">
{ decodedTitle }
</p>
</div>
<p className="m-0 font-normal text-text-secondary line-clamp-3 leading-5 text-sm">
{ decodedDescription || '' }
</p>
</div>
</div>
</div>
</div>
</div>
);
};
const SocialPreview = ( {
displayName = 'Name',
username = '@username',
type = 'facebook',
title = __( 'Sample Post - Testing Site', 'surerank' ),
description = '',
imageURL = '',
siteURL = 'surerank.com',
twitterLargePreview = false,
onClickRemove,
hideRemoveButton = true,
forMetaBox = false,
} ) => {
let designContent = null;
const decoded_description = decodeHtmlEntities( description );
const decoded_title = decodeHtmlEntities( title );
const descriptionContent = decoded_description || '';
switch ( type ) {
case 'twitter':
designContent = (
<TwitterPreview
displayName={ displayName }
username={ username }
timeLabel={ getDateString( 'twitter' ) }
title={ decoded_title }
description={ decoded_description }
imageURL={ imageURL }
siteURL={ siteURL }
onClickRemove={ onClickRemove }
hideRemoveButton={ hideRemoveButton }
forMetaBox={ forMetaBox }
cardType={
twitterLargePreview ? 'summary_large_image' : 'summary'
}
/>
);
break;
case 'facebook':
designContent = (
<>
{ /* Image */ }
<div className="w-full h-[16.8125rem] overflow-clip">
{ imageURL ? (
<div className="relative w-full h-full">
<img
src={ imageURL }
alt="Social Post"
className="w-full h-full object-cover"
/>
{ ! hideRemoveButton && (
<GlobalRemoveButton
onClick={ onClickRemove }
/>
) }
</div>
) : (
<ImagePlaceholder />
) }
</div>
{ /* Footer */ }
<div className="p-3 w-full">
<p className="m-0 text-xs leading-4 font-normal text-text-secondary">
{ siteURL }
</p>
<p className="mt-1.5 mb-1 text-base leading-6 font-semibold text-text-primary line-clamp-2">
{ decoded_title }
</p>
<p className="m-0 text-sm leading-5 font-normal line-clamp-2">
{ descriptionContent }
</p>
</div>
</>
);
break;
default:
designContent = null;
break;
}
return (
<div className="p-2 rounded-lg bg-background-secondary">
<div className="flex flex-col rounded-md border border-solid border-border-subtle shadow-sm overflow-hidden bg-background-primary">
{ designContent }
</div>
</div>
);
};
export default SocialPreview;