All files / src/components/pages/user/profile/profile-edit-fields/image-field index.tsx

100% Statements 54/54
75% Branches 3/4
100% Functions 2/2
100% Lines 54/54

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 551x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x 51x  
import { AnyFieldApi } from '@tanstack/react-form';
 
import { Icon } from '@/components/icon';
import { ImageInput, ImageInputProps, ImageWithFallback } from '@/components/ui';
import { cn } from '@/lib/utils';
 
type ImageUploadPropsWithoutChildren = Omit<ImageInputProps, 'children'>;
 
interface Props extends ImageUploadPropsWithoutChildren {
  field: AnyFieldApi;
}
export const ImageField = ({ field, initialImages }: Props) => {
  return (
    <div className='flex-center py-6'>
      <ImageInput
        initialImages={initialImages}
        maxFiles={1}
        mode='replace'
        multiple={false}
        value={field.state.value}
        onChange={field.handleChange}
      >
        {(images, _onRemoveImageClick, onFileSelectClick) => {
          const nextImages = Object.keys(images).length > 0 ? images : { '': null };
          return (
            <>
              {Object.entries(nextImages).map(([url, _file]) => (
                <div key={url} className='relative aspect-square size-24'>
                  <ImageWithFallback
                    className='rounded-full border-1 border-[rgba(0,0,0,0.04)]'
                    alt='프로필 이미지'
                    fill
                    src={url}
                  />
                  <button
                    className={cn(
                      'flex-center absolute -right-1.75 bottom-0 size-8 cursor-pointer rounded-full border-1 border-gray-300 bg-gray-100',
                      'hover:scale-110 hover:bg-gray-200',
                      'transition-all duration-300',
                    )}
                    type='button'
                    onClick={onFileSelectClick}
                  >
                    <Icon id='edit' className='size-5 text-gray-600' />
                  </button>
                </div>
              ))}
            </>
          );
        }}
      </ImageInput>
    </div>
  );
};