-
Notifications
You must be signed in to change notification settings - Fork 3
[Fix/style] 수정 중 입니다 !!!!! #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { toast } from "react-hot-toast"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useDeleteWish, useGetWishList, usePostAddWish } from "@/apis/universities"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import useAuthStore from "@/lib/zustand/useAuthStore"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { IconShare, IconShareFilled } from "@/public/svgs"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const likeIcon = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <svg xmlns="http://www.w3.org/2000/svg" width="19" height="16" viewBox="0 0 19 16" fill="none"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -24,25 +25,14 @@ const likeIconFilled = ( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const copyIcon = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <svg xmlns="http://www.w3.org/2000/svg" width="17" height="19" viewBox="0 0 17 19" fill="none"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| d="M8.5 2.13333V11.7667M11.7143 4.4L8.5 1L5.28571 4.4M1 10.0667V15.7333C1 16.3345 1.22576 16.911 1.62763 17.3361C2.02949 17.7612 2.57454 18 3.14286 18H13.8571C14.4255 18 14.9705 17.7612 15.3724 17.3361C15.7742 16.911 16 16.3345 16 15.7333V10.0667" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stroke="#4672EE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stroke-width="2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stroke-linecap="round" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stroke-linejoin="round" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface UniversityBtnsProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| universityId: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const UniversityBtns = ({ universityId }: UniversityBtnsProps) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isAuthenticated = useAuthStore((state) => state.isAuthenticated); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isLiked, setIsLiked] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isShareActive, setIsShareActive] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: favoriteUniv } = useGetWishList(isAuthenticated); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { mutate: postUniversityFavorite } = usePostAddWish(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { mutate: deleteUniversityFavorite } = useDeleteWish(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -64,6 +54,8 @@ const UniversityBtns = ({ universityId }: UniversityBtnsProps) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleCopy = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| navigator.clipboard.writeText(window.location.href).then(() => {}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| toast.success("URL이 복사되었습니다."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsShareActive(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTimeout(() => setIsShareActive(false), 600); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -86,10 +78,20 @@ const UniversityBtns = ({ universityId }: UniversityBtnsProps) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isLiked ? likeIconFilled : likeIcon} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="button" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={handleCopy} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={`/* stroke: #FFF; stroke-width: 1px; */ /* fill: linear-gradient(...) */ /* CSS의 fill은 SVG 속성이지만, 버튼 배경으로 적용합니다. */ /* backdrop-filter: blur(2px); */ /* filter: drop-shadow(...) */ /* 기타 스타일 */ rounded-full border border-white/80 bg-[linear-gradient(136deg,rgba(255,255,255,0.4)_14.87%,rgba(199,212,250,0.8)_89.1%)] p-3 drop-shadow-[2px_2px_6px_#C7D4FA] backdrop-blur-[2px] transition-transform duration-200 ease-in-out hover:scale-110 focus:outline-none focus:ring-2 focus:ring-white/50 active:scale-95`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className="relative h-10 w-10 transition-transform duration-200 ease-in-out hover:scale-110 focus:outline-none active:scale-95" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {copyIcon} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <IconShare | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width={40} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height={40} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={`absolute inset-0 transition-opacity duration-300 ease-in-out ${isShareActive ? "opacity-0" : "opacity-100"}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <IconShareFilled | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width={40} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height={40} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={`absolute inset-0 transition-opacity duration-300 ease-in-out ${isShareActive ? "opacity-100" : "opacity-0"}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
80
to
95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 공유 버튼의 키보드 접근성 개선이 필요합니다. 아이콘 전환 애니메이션 구현은 깔끔하지만, 버튼에 포커스 인디케이터가 없어 키보드 네비게이션 사용자가 현재 포커스 위치를 파악하기 어렵습니다. 위의 좋아요 버튼(Line 76)에는 ♿ 접근성 개선 제안 <button
type="button"
onClick={handleCopy}
- className="relative h-10 w-10 transition-transform duration-200 ease-in-out hover:scale-110 focus:outline-none active:scale-95"
+ className="relative h-10 w-10 rounded-full transition-transform duration-200 ease-in-out hover:scale-110 focus:outline-none focus:ring-2 focus:ring-white/50 active:scale-95"
>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import Image from "@/components/ui/FallbackImage"; | ||
| import type { Article } from "@/types/news"; | ||
| import { normalizeImageUrlToUploadCdn } from "@/utils/cdnUrl"; | ||
|
|
||
| interface ArticlePreviewProps { | ||
| article: Article; | ||
| } | ||
|
|
||
| const ArticlePreview = ({ article }: ArticlePreviewProps) => { | ||
| const thumbnailUrl = normalizeImageUrlToUploadCdn(article.thumbnailUrl); | ||
| return ( | ||
| <a | ||
| href={article.url} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="block overflow-hidden rounded-lg bg-k-50 transition-opacity hover:opacity-90" | ||
| > | ||
| <div className="relative h-32 w-full bg-gradient-to-br from-blue-400 to-blue-600"> | ||
| <Image src={thumbnailUrl} alt={article.title} fill className="object-cover" /> | ||
| </div> | ||
| <p className="line-clamp-1 px-3 py-2 text-k-800 typo-sb-7">{article.title}</p> | ||
| </a> | ||
| ); | ||
| }; | ||
|
|
||
| export default ArticlePreview; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
공유 기능 구현에서 두 가지 개선이 필요합니다.
다음 사항들을 확인해 주세요:
클립보드 API 에러 처리 누락 (Line 55)
navigator.clipboard.writeText()의 빈.then()콜백이 불필요하며, 실패 시 처리를 위한.catch()핸들러가 없습니다.메모리 누수 가능성 (Lines 57-58)
setTimeout이 정리(cleanup)되지 않아, 600ms 이내에 컴포넌트가 언마운트되면 언마운트된 컴포넌트에 상태 업데이트를 시도하게 됩니다.🔧 개선된 구현 제안
🤖 Prompt for AI Agents