Skip to content

Commit

Permalink
Merge branch 'fe-develop' of https://github.com/Kernel360/F2-BAGUNI i…
Browse files Browse the repository at this point in the history
…nto front/feat/#876
  • Loading branch information
dmdgpdi committed Dec 27, 2024
2 parents d79c8b1 + a1cde58 commit e82be12
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 32 deletions.
4 changes: 2 additions & 2 deletions frontend/techpick/src/components/DragOverlay/DragOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
} from '@/stores';
import { dragCountStyle, stackedOverlayStyle } from './dragOverlay.css';
import { FolderItemOverlay } from './FolderItemOverlay';
import { PickCarouselCardOverlay } from './PickCarouselCardOverlay';
import { PickDragOverlayShadowList } from './PickDragOverlayShadowList';
import { PickRecordOverlay } from './PickRecordOverlay';
import { PickCarouselCard } from '../RecommendedPickCarousel/PickCarouselCard';

export function DargOverlay({ elementClickPosition }: DargOverlayProps) {
const { isDragging: isFolderDragging, draggingFolderInfo } = useTreeStore();
Expand Down Expand Up @@ -67,7 +67,7 @@ export function DargOverlay({ elementClickPosition }: DargOverlayProps) {
if (isRecommendPickDragging && draggingRecommendPickInfo) {
return (
<DragOverlayPrimitive style={recommendPickOverlayStyle}>
<PickCarouselCard recommendPick={draggingRecommendPickInfo} />
<PickCarouselCardOverlay recommendPick={draggingRecommendPickInfo} />
</DragOverlayPrimitive>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client';

import Image from 'next/image';
import { postRecommendPickViewEventLog } from '@/apis/eventLog';
import { useOpenUrlInNewTab, useImageLoader } from '@/hooks';
import {
pickCarouselItemStyle,
pickTitleStyle,
pickImageStyle,
defaultImageStyle,
defaultImageLayoutStyle,
} from '../RecommendedPickCarousel/pickCarouselCard.css';
import { RecommendPickType } from '@/types';

export function PickCarouselCardOverlay({
recommendPick,
}: PickCarouselCardOverlayProps) {
const { openUrlInNewTab } = useOpenUrlInNewTab(recommendPick.url);
const { imageStatus } = useImageLoader(recommendPick.imageUrl);

const onOpenLink = async () => {
try {
openUrlInNewTab();
await postRecommendPickViewEventLog({ url: recommendPick.url });
} catch {
/*empty */
}
};

return (
<div className={pickCarouselItemStyle} onClick={onOpenLink}>
{imageStatus === 'loaded' ? (
<img
src={recommendPick.imageUrl}
alt=""
className={pickImageStyle}
width="250"
height="131"
/>
) : (
<div className={defaultImageLayoutStyle}>
<Image
src={'/image/default_image.svg'}
alt=""
className={`${defaultImageStyle}`}
width="80"
height="65"
/>
</div>
)}

<p className={pickTitleStyle}>{recommendPick.title}</p>
</div>
);
}

interface PickCarouselCardOverlayProps {
recommendPick: RecommendPickType;
}
26 changes: 15 additions & 11 deletions frontend/techpick/src/components/DragOverlay/PickRecordOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Image from 'next/image';
import { ExternalLink as ExternalLinkIcon } from 'lucide-react';
import { useImageLoader } from '@/hooks';
import { useTagStore } from '@/stores';
import { formatDateString } from '@/utils';
import { pickRecordOverlayLayoutStyle } from './pickRecordOverlay.css';
Expand All @@ -13,6 +14,7 @@ import {
dateTextStyle,
linkLayoutStyle,
externalLinkIconStyle,
imageStyle,
} from '../PickRecord/pickRecord.css';
import { PickTagColumnLayout } from '../PickRecord/PickTagColumnLayout';
import { PickTitleColumnLayout } from '../PickRecord/PickTitleColumnLayout';
Expand All @@ -24,24 +26,26 @@ export function PickRecordOverlay({ pickInfo }: PickViewItemComponentProps) {
const pick = pickInfo;
const link = pickInfo.linkInfo;
const { findTagById } = useTagStore();
const { imageStatus } = useImageLoader(link.imageUrl);

const filteredSelectedTagList: TagType[] = [];

pickInfo.tagIdOrderedList.forEach((tagId) => {
const tagInfo = findTagById(tagId);
if (tagInfo) {
filteredSelectedTagList.push(tagInfo);
}
});
const filteredSelectedTagList: TagType[] = pickInfo.tagIdOrderedList
.map((tagId) => findTagById(tagId))
.filter((tag): tag is TagType => tag !== undefined);

return (
<div className={pickRecordOverlayLayoutStyle}>
<PickImageColumnLayout>
<div className={pickImageStyle}>
{link.imageUrl ? (
<Image src={link.imageUrl} alt="" fill />
{imageStatus === 'loaded' ? (
<img
src={link.imageUrl}
alt=""
width="96px"
height="47.25px"
className={imageStyle}
/>
) : (
<Image src={'/image/default_image.svg'} alt="" fill sizes="96px" />
<Image src="/image/default_image.svg" alt="" fill sizes="96px" />
)}
</div>
</PickImageColumnLayout>
Expand Down
9 changes: 5 additions & 4 deletions frontend/techpick/src/components/PickRecord/PickRecord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useState } from 'react';
import Image from 'next/image';
import { ExternalLink as ExternalLinkIcon } from 'lucide-react';
import { postUserPickViewEventLog } from '@/apis/eventLog';
import { useOpenUrlInNewTab } from '@/hooks';
import { useImageLoader, useOpenUrlInNewTab } from '@/hooks';
import { usePickStore, useTagStore, useUpdatePickStore } from '@/stores';
import { formatDateString } from '@/utils';
import { PickDateColumnLayout } from './PickDateColumnLayout';
Expand Down Expand Up @@ -39,6 +39,7 @@ export function PickRecord({ pickInfo }: PickViewItemComponentProps) {
const [isHovered, setIsHovered] = useState(false);
const isUpdateTitle = currentUpdateTitlePickId === pickInfo.id;
const { isDragging } = usePickStore();
const { imageStatus } = useImageLoader(link.imageUrl);

const filteredSelectedTagList: TagType[] = [];

Expand Down Expand Up @@ -66,16 +67,16 @@ export function PickRecord({ pickInfo }: PickViewItemComponentProps) {
>
<PickImageColumnLayout>
<div className={pickImageStyle}>
{link.imageUrl && link.imageUrl !== '' ? (
{imageStatus === 'error' ? (
<Image src={'/image/default_image.svg'} alt="" fill sizes="96px" />
) : (
<img
src={link.imageUrl}
alt=""
width="96px"
height="47.25px"
className={imageStyle}
/>
) : (
<Image src={'/image/default_image.svg'} alt="" fill sizes="96px" />
)}
</div>
</PickImageColumnLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useState } from 'react';
import Image from 'next/image';
import { ExternalLink as ExternalLinkIcon } from 'lucide-react';
import { postSharedPickViewEventLog } from '@/apis/eventLog';
import { useOpenUrlInNewTab } from '@/hooks';
import { useImageLoader, useOpenUrlInNewTab } from '@/hooks';
import { formatDateString } from '@/utils';
import { PickDateColumnLayout } from './PickDateColumnLayout';
import { PickImageColumnLayout } from './PickImageColumnLayout';
Expand Down Expand Up @@ -38,6 +38,7 @@ export function SharePickRecord({
const link = pickInfo.linkInfo!;
const { openUrlInNewTab } = useOpenUrlInNewTab(link.url);
const [isHovered, setIsHovered] = useState(false);
const { imageStatus } = useImageLoader(link.imageUrl);

const onClickLink = async () => {
try {
Expand All @@ -60,16 +61,16 @@ export function SharePickRecord({
>
<PickImageColumnLayout>
<div className={pickImageStyle}>
{link.imageUrl && link.imageUrl !== '' ? (
{imageStatus === 'error' ? (
<Image src={'/image/default_image.svg'} alt="" fill sizes="96px" />
) : (
<img
src={link.imageUrl}
alt=""
width="96px"
height="47.25px"
className={imageStyle}
/>
) : (
<Image src={'/image/default_image.svg'} alt="" fill sizes="96px" />
)}
</div>
</PickImageColumnLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Image from 'next/image';
import { postRecommendPickViewEventLog } from '@/apis/eventLog';
import { useOpenUrlInNewTab } from '@/hooks';
import { useOpenUrlInNewTab, useImageLoader } from '@/hooks';
import {
pickCarouselItemStyle,
pickTitleStyle,
Expand All @@ -14,6 +14,7 @@ import { RecommendPickType } from '@/types';

export function PickCarouselCard({ recommendPick }: PickCarouselCardProps) {
const { openUrlInNewTab } = useOpenUrlInNewTab(recommendPick.url);
const { imageStatus } = useImageLoader(recommendPick.imageUrl);

const onOpenLink = async () => {
try {
Expand All @@ -26,7 +27,19 @@ export function PickCarouselCard({ recommendPick }: PickCarouselCardProps) {

return (
<div className={pickCarouselItemStyle} onClick={onOpenLink}>
{recommendPick.imageUrl === '' ? (
{imageStatus === 'loading' && (
<div className={defaultImageLayoutStyle}></div>
)}
{imageStatus === 'loaded' && (
<img
src={recommendPick.imageUrl}
alt=""
className={pickImageStyle}
width="250"
height="131"
/>
)}
{imageStatus === 'error' && (
<div className={defaultImageLayoutStyle}>
<Image
src={'/image/default_image.svg'}
Expand All @@ -36,16 +49,7 @@ export function PickCarouselCard({ recommendPick }: PickCarouselCardProps) {
height="65"
/>
</div>
) : (
<img
src={recommendPick.imageUrl}
alt=""
className={pickImageStyle}
width="250"
height="131"
/>
)}

<p className={pickTitleStyle}>{recommendPick.title}</p>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions frontend/techpick/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { useDisclosure } from './useDisclosure';
export { useRecommendPickToFolderDndMonitor } from './useRecommendPickToFolderDndMonitor';
export { useLocalStorage } from './useLocalStorage';
export { useEventLogger } from './useEventLogger';
export { useImageLoader } from './useImageLoader';
33 changes: 33 additions & 0 deletions frontend/techpick/src/hooks/useImageLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useState, useLayoutEffect } from 'react';

type ImageStatus = 'loading' | 'loaded' | 'error';

/**
*
* @param imageUrl
* @description imageUrl의 상태를 나타냅니다. 'loading' | 'loaded' | 'error'
* @returns imageStatus
*/

export function useImageLoader(imageUrl: string | undefined) {
const [imageStatus, setImageStatus] = useState<ImageStatus>('loading');

useLayoutEffect(() => {
if (!imageUrl) {
setImageStatus('error');
return;
}

const img = new window.Image();
img.onload = () => setImageStatus('loaded');
img.onerror = () => setImageStatus('error');
img.src = imageUrl;

return () => {
img.onload = null;
img.onerror = null;
};
}, [imageUrl]);

return { imageStatus };
}

0 comments on commit e82be12

Please sign in to comment.