0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Added cover image interaction to user details

refs. https://github.com/TryGhost/Team/issues/3351
This commit is contained in:
Peter Zimon 2023-06-02 14:29:46 +02:00
parent 3090fc6067
commit 82b56c319e
6 changed files with 50 additions and 23 deletions

View file

@ -9,7 +9,7 @@ export interface FileUploadProps {
children?: React.ReactNode;
className?: string;
onUpload: (file: File) => void;
style: {}
style?: {}
}
const FileUpload: React.FC<FileUploadProps> = ({id, onUpload, children, style, ...props}) => {

View file

@ -15,7 +15,7 @@ type Story = StoryObj<typeof ImageUpload>;
export const Default: Story = {
args: {
id: 'image-upload-test',
label: 'Upload image',
children: 'Upload image',
onUpload: (file: File) => {
alert(`You're uploading: ${file.name}`);
}
@ -25,7 +25,7 @@ export const Default: Story = {
export const Resized: Story = {
args: {
id: 'image-upload-test',
label: 'Upload image',
children: 'Upload image',
width: '480px',
height: '320px',
onUpload: (file: File) => {
@ -37,7 +37,7 @@ export const Resized: Story = {
export const ImageUploaded: Story = {
args: {
id: 'image-upload-test',
label: 'Upload image',
children: 'Upload image',
width: '480px',
height: '320px',
imageURL: 'https://images.unsplash.com/photo-1685374156924-5230519f4ab3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8YWxsfDI1fHx8fHx8Mnx8MTY4NTYzNzE3M3w&ixlib=rb-4.0.3&q=80&w=2000',

View file

@ -4,44 +4,52 @@ import React from 'react';
interface ImageUploadProps {
id: string;
label: React.ReactNode;
children?: React.ReactNode;
width?: string;
height?: string;
imageURL?: string;
imageClassName?: string;
fileUploadClassName?: string;
deleteButtonClassName?: string;
deleteButtonContent?: React.ReactNode;
onUpload: (file: File) => void;
onDelete: () => void;
}
const ImageUpload: React.FC<ImageUploadProps> = ({
id,
label,
children,
width,
height = '120px',
imageURL,
imageClassName = 'group relative bg-cover',
fileUploadClassName = 'flex cursor-pointer items-center justify-center rounded border border-grey-100 bg-grey-75 p-3 text-sm font-semibold text-grey-800 hover:text-black',
deleteButtonClassName = 'invisible absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-[rgba(0,0,0,0.75)] text-white hover:bg-black group-hover:!visible',
deleteButtonContent = <Icon color='white' name='trash' size='sm' />,
onUpload,
onDelete
}) => {
if (imageURL) {
return (
<div className='group relative bg-cover' style={{
<div className={imageClassName} style={{
width: width,
height: height,
backgroundImage: `url(${imageURL})`
}}>
<button className='invisible absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-[rgba(0,0,0,0.75)] text-white hover:bg-black group-hover:!visible' type='button' onClick={onDelete}>
<Icon color='white' name='trash' size='sm' />
<button className={deleteButtonClassName} type='button' onClick={onDelete}>
{deleteButtonContent}
</button>
</div>
);
} else {
return (
<FileUpload className={`flex cursor-pointer items-center justify-center rounded border border-grey-100 bg-grey-75 p-3 text-sm font-semibold text-grey-800 hover:text-black`} id={id} style={
<FileUpload className={fileUploadClassName} id={id} style={
{
width: width,
height: height
}
} onUpload={onUpload}>
{label}
{children}
</FileUpload>
);
}

View file

@ -51,10 +51,11 @@ const Facebook: React.FC = () => {
height='200px'
id='twitter-image'
imageURL={facebookImage}
label='Upload Facebook image'
onDelete={handleImageDelete}
onUpload={handleImageUpload}
/>
>
Upload Facebook image
</ImageUpload>
<TextField
inputRef={focusRef}
placeholder={siteTitle}

View file

@ -55,10 +55,11 @@ const Twitter: React.FC = () => {
height='200px'
id='twitter-image'
imageURL={twitterImage}
label='Upload twitter image'
onDelete={handleImageDelete}
onUpload={handleImageUpload}
/>
>
Upload twitter image
</ImageUpload>
<TextField
inputRef={focusRef}
placeholder={siteTitle}

View file

@ -3,6 +3,7 @@ import Button from '../../../../admin-x-ds/global/Button';
import ConfirmationModal from '../../../../admin-x-ds/global/ConfirmationModal';
import Heading from '../../../../admin-x-ds/global/Heading';
import Icon from '../../../../admin-x-ds/global/Icon';
import ImageUpload from '../../../../admin-x-ds/global/ImageUpload';
import Menu from '../../../../admin-x-ds/global/Menu';
import Modal from '../../../../admin-x-ds/global/Modal';
import NiceModal from '@ebay/nice-modal-react';
@ -387,7 +388,9 @@ interface UserDetailModalProps {
}
const UserMenuTrigger = () => (
<Button color='white' icon='menu-horizontal' size='sm' />
<div className='flex h-8 cursor-pointer items-center justify-center rounded bg-[rgba(0,0,0,0.75)] px-3 opacity-80 hover:opacity-100'>
<Icon color='white' name='menu-horizontal' size='sm' />
</div>
);
const confirmMakeOwner = () => {
@ -466,6 +469,8 @@ const UserDetailModal:React.FC<UserDetailModalProps> = ({user, updateUser}) => {
}
}, [saveState]);
const fileUploadButtonClasses = 'absolute right-[104px] bottom-12 bg-[rgba(0,0,0,0.75)] rounded text-sm text-white flex items-center justify-center px-3 h-8 opacity-80 hover:opacity-100 transition cursor-pointer font-medium';
return (
<Modal
okColor='green'
@ -478,21 +483,33 @@ const UserDetailModal:React.FC<UserDetailModalProps> = ({user, updateUser}) => {
}}
>
<div>
<div className={`relative -mx-12 -mt-12 bg-gradient-to-tr from-grey-900 to-black p-12`} style={userData.cover_image ? {backgroundImage: `url(${userData.cover_image})`, backgroundSize: 'cover'} : {}}>
{userData.cover_image && (
<div className='absolute inset-0 z-0 block bg-gradient-to-tr from-[rgba(0,0,0,0.5)] to-[rgba(0,0,0,0.01)]'></div>
)}
<div className="absolute right-8 top-8">
<div className={`relative -mx-12 -mt-12 bg-gradient-to-tr from-grey-900 to-black`}>
<ImageUpload
deleteButtonClassName={fileUploadButtonClasses}
deleteButtonContent='Delete cover image'
fileUploadClassName={fileUploadButtonClasses}
height={userData.cover_image ? '100%' : '32px'}
id='cover-image'
imageClassName='absolute inset-0 bg-cover group'
imageURL={userData.cover_image || ''}
onDelete={() => {
alert('deleted');
}}
onUpload={() => {
alert('uploaded');
}}
>Upload cover image</ImageUpload>
<div className="absolute bottom-12 right-12">
<Menu items={menuItems} position='left' trigger={<UserMenuTrigger />}></Menu>
</div>
<div className='relative z-10 mt-60 flex gap-4'>
<div className='pointer-events-none relative z-10 flex gap-4 px-12 pb-12 pt-60'>
<Avatar bgColor={generateAvatarColor((userData.name ? userData.name : userData.email))} className='-ml-1' image={userData.profile_image} label={getInitials(userData.name)} labelColor='white' size='xl' />
<div>
<Heading styles='text-white'>{user.name}</Heading>
<span className='text-md font-semibold text-white'>Administrator</span>
</div>
</div>
</div>
</div>
<div className='mt-10 grid grid-cols-2 gap-x-12 gap-y-20 pb-10'>
<Basic setUserData={setUserData} user={userData} />
<Details setUserData={setUserData} user={userData} />