-
Notifications
You must be signed in to change notification settings - Fork 4
add hero area in home #77
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
Conversation
- Add BackButton, Footer, and Recommend components to project pages - Replace text logo with SymbolIcon in Header and Sidebar - Add new project content (Millie Renewal) - Update redirects in next.config.ts - Fix lint errors
…lay them on project detail pages and cards.
…and new sort options
… and add `cmdk` dependency.
…pect ratio, and adding a gap between cards.
…and integrate them into a new contact buttons component.
…d links on the about page, populating the certificate section.
…page and update project content.
…oltips, checkmark icons, and new entries.
…and update dependencies.
…and update dependencies.
…ng, and import Instrument Serif font.
People can be co-author:
|
❌ Deploy Preview for semantic-template failed. Why did it fail? →
|
Summary of ChangesHello @sepowered, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 Pull Request는 블로그의 기술 스택을 Gatsby.js에서 Next.js로 전환하고, 개인 포트폴리오를 체계적으로 보여줄 수 있는 'Projects' 섹션을 도입하여 블로그의 전반적인 기능과 사용자 경험을 크게 향상시키는 것을 목표로 합니다. Cloudflare R2를 활용한 이미지 및 파일 관리 시스템을 구축하여 성능과 보안을 강화했으며, 새로운 UI 컴포넌트와 상세한 'About' 페이지를 통해 방문자에게 더욱 풍부하고 인터랙티브한 정보를 제공합니다. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Code Review
이번 PR은 홈 화면에 히어로 영역을 추가하는 것 이상의 많은 변경 사항을 포함하고 있네요. 프로젝트 포트폴리오 기능 추가, 블로그 콘텐츠 마이그레이션, 전반적인 사이트 구조 리팩터링 등 대규모 업데이트가 이루어졌습니다. 제목이 이러한 변경 범위를 충분히 반영하지 못하는 점은 아쉽지만, 새롭게 추가된 프로젝트 필터링 기능과 전체적인 디자인 개선은 매우 인상적입니다. 몇 가지 기술적인 개선점과 오타 수정을 제안드립니다.
| <a | ||
| href="#" | ||
| className="relative overflow-hidden flex-1 flex items-center justify-center gap-2 px-4 py-3 hover:brightness-95 transition-all border-l border-b border-r border-t-0 border-[rgba(0,0,0,0.03)] rounded-none tablet:rounded-bl-[0.875rem] shadow-[inset_0_-0.125rem_0.125rem_rgba(255,255,255,0.3)]" | ||
| style={{ | ||
| backgroundColor: PROFILE.cardBackgroundColor, | ||
| color: PROFILE.contentTextColor, | ||
| }} | ||
| > | ||
| <div className="absolute inset-0 bg-white/20 pointer-events-none" /> | ||
| <div className="relative z-10 flex items-center gap-2"> | ||
| <DownloadIcon size={20} /> | ||
| <span className="font-medium">이력서 다운로드</span> | ||
| </div> | ||
| </a> | ||
| <a | ||
| href="#" | ||
| className="relative overflow-hidden flex-1 flex items-center justify-center gap-2 px-4 py-3 hover:brightness-95 transition-all border-l border-b border-r border-t-0 tablet:border-l-0 border-[rgba(0,0,0,0.03)] rounded-b-[0.875rem] tablet:rounded-bl-none tablet:rounded-br-[0.875rem] shadow-[inset_0_-0.125rem_0.125rem_rgba(255,255,255,0.3)]" | ||
| style={{ | ||
| backgroundColor: PROFILE.cardBackgroundColor, | ||
| color: PROFILE.contentTextColor, | ||
| }} | ||
| > | ||
| <div className="absolute inset-0 bg-white/20 pointer-events-none" /> | ||
| <div className="relative z-10 flex items-center gap-2"> | ||
| <DownloadIcon size={20} /> | ||
| <span className="font-medium">자기소개서 다운로드</span> | ||
| </div> | ||
| </a> | ||
| </div> |
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.
| @@ -0,0 +1,78 @@ | |||
| 'use client'; | |||
|
|
|||
| // @ts-expect-error - LogoLoop is JSX | |||
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.
| .sort((a, b) => { | ||
| if (sortOption === 'recommended') { | ||
| if (a.order !== undefined && b.order !== undefined) return a.order - b.order; | ||
| if (a.order !== undefined) return -1; | ||
| if (b.order !== undefined) return 1; | ||
| return dayjs(a.createdAt).isAfter(dayjs(b.createdAt)) ? -1 : 1; | ||
| } | ||
| if (sortOption === 'newest') { | ||
| return dayjs(a.createdAt).isAfter(dayjs(b.createdAt)) ? -1 : 1; | ||
| } | ||
| if (sortOption === 'alphabetical') { | ||
| return a.title.localeCompare(b.title); | ||
| } | ||
| return 0; | ||
| }); |
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.
| const DownloadButton = ({ | ||
| children, | ||
| href, | ||
| type = 'default', | ||
| ...props | ||
| }: ComponentProps<'a'> & { type?: 'default' | 'pdf' }) => { | ||
| const [isLoading, setIsLoading] = useState(false); | ||
|
|
||
| useEffect(() => { | ||
| if (isLoading) { | ||
| const timer = setTimeout(() => { | ||
| setIsLoading(false); | ||
| if (href) window.open(href, '_blank'); | ||
| }, 400); | ||
|
|
||
| return () => clearTimeout(timer); | ||
| } | ||
| }, [isLoading, href]); | ||
|
|
||
| const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => { | ||
| e.preventDefault(); | ||
| if (!isLoading) { | ||
| setIsLoading(true); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <a | ||
| href={href} | ||
| onClick={handleClick} | ||
| className="flex items-center justify-center w-full tablet:w-fit px-4 py-3 border border-[var(--color-border)] rounded-xl bg-[var(--color-background)] hover:bg-[var(--color-gray-hover)] transition-colors duration-200 cursor-pointer no-underline relative overflow-hidden min-h-[52px] min-w-[280px]" | ||
| {...props} | ||
| > | ||
| {/* Default Content - Keeps height fixed */} | ||
| <div | ||
| className={`flex items-center justify-between w-full gap-3 transition-opacity duration-200 ${ | ||
| isLoading ? 'opacity-0' : 'opacity-100' | ||
| }`} | ||
| > | ||
| <div className="flex items-center gap-2"> | ||
| <span className="text-xl">{type === 'pdf' ? '📄' : '📎'}</span> | ||
| <span className="font-medium text-[var(--color-gray-bold)]">{children}</span> | ||
| </div> | ||
| <svg | ||
| width="15" | ||
| height="15" | ||
| viewBox="0 0 15 15" | ||
| fill="none" | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| className="text-[var(--color-gray-mid)]" | ||
| > | ||
| <path | ||
| d="M3.64645 11.3536C3.45118 11.1583 3.45118 10.8417 3.64645 10.6465L10.2929 4L6 4C5.72386 4 5.5 3.77614 5.5 3.5C5.5 3.22386 5.72386 3 6 3L11.5 3C11.7761 3 12 3.22386 12 3.5L12 9C12 9.27614 11.7761 9.5 11.5 9.5C11.2239 9.5 11 9.27614 11 9L11 4.70711L4.35355 11.3536C4.15829 11.5488 3.84171 11.5488 3.64645 11.3536Z" | ||
| fill="currentColor" | ||
| fillRule="evenodd" | ||
| clipRule="evenodd" | ||
| /> | ||
| </svg> | ||
| </div> | ||
|
|
||
| {/* Loading Overlay */} | ||
| <AnimatePresence> | ||
| {isLoading && ( | ||
| <motion.div | ||
| initial={{ opacity: 0, y: 10 }} | ||
| animate={{ opacity: 1, y: 0 }} | ||
| exit={{ opacity: 0, y: -10 }} | ||
| transition={{ duration: 0.2 }} | ||
| className="absolute inset-0 flex items-center justify-center gap-3 bg-[var(--color-background)]" | ||
| > | ||
| <div className="relative w-5 h-5 animate-spin"> | ||
| <svg className="w-full h-full" viewBox="0 0 24 24"> | ||
| <circle | ||
| className="text-[var(--color-border)]" | ||
| strokeWidth="3" | ||
| stroke="currentColor" | ||
| fill="transparent" | ||
| r="10" | ||
| cx="12" | ||
| cy="12" | ||
| /> | ||
| <circle | ||
| className="text-[var(--color-primary)]" | ||
| strokeWidth="3" | ||
| strokeDasharray={15} | ||
| strokeDashoffset={15} | ||
| strokeLinecap="round" | ||
| stroke="currentColor" | ||
| fill="transparent" | ||
| r="10" | ||
| cx="12" | ||
| cy="12" | ||
| /> | ||
| </svg> | ||
| </div> | ||
| <span className="font-medium text-[var(--color-gray-bold)] text-sm"> | ||
| 파일을 여는 중이에요... | ||
| </span> | ||
| </motion.div> | ||
| )} | ||
| </AnimatePresence> | ||
| </a> | ||
| ); | ||
| }; |
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.
| 생성형 인공지능은 기존의 제품과 다른 상호작용 방식을 사용합니다. 제가 느끼는 가장 큰 차이는 기존의 제품은 내가 정보를 탐색해야 한다면, 생성형 인공지능을 사용하게 되면 그러한 기능을 사용자가 아닌 제품 스스로가 수행하게 된다는 점입니다. | ||
|  | ||
|
|
||
| Google와 같은 검색엔진에서 정보를 찾기 위해서는 여러 웹사이트를 직접 돌아가면서 **나에게 적합한 정보인지 판단하고, 아닌 경우에는 다시 찾는** 작업을 나 지신이 수행해야합니다. |
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.
|
|
||
|  | ||
|
|
||
| 그리고 이것을 시도하면 GitHub 차원에서 막습니다. 깃허브를 제외하고도 토큰은 정말 비밀번호 같은 것이기에 AWS의 권한이 탈취뒤어서 보지도 못한 스팟 인스턴스가 무수히 생기고 코인을 채굴하는 피해가 생기는 등... 수많은 사람들이 토큰을 올리다 흘린 눈물이 저를 살리게 된것입니다. 전세계 개발자분들께 감사 드립니다. |
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.
No description provided.