Skip to content

feat(profile): complete #46 — profile feature + auth/upload fixes#146

Merged
thxforall merged 16 commits into
devfrom
feature/46-profile-completion
Apr 9, 2026
Merged

feat(profile): complete #46 — profile feature + auth/upload fixes#146
thxforall merged 16 commits into
devfrom
feature/46-profile-completion

Conversation

@thxforall
Copy link
Copy Markdown
Contributor

Summary

  • Profile 실데이터 연동: Backend stats/activities API에 실제 COUNT 쿼리 추가 (기존 하드코딩 0 제거)
  • Follow/Unfollow API: Rust backend 엔드포인트 + Next.js 프록시 + FollowButton 컴포넌트
  • Avatar Upload: Supabase Storage 파일 업로드로 전환 (기존 URL 텍스트 입력 제거)
  • Style DNA 편집: 키워드 태그 + 컬러 피커 모달
  • Rankings 페이지: /rankings 라우트 + API 프록시
  • Auth 리다이렉트 수정: implicit OAuth flow에서 proxy.ts 서버사이드 세션 체크 스킵
  • Upload API 수정: NEXT_PUBLIC_API_BASE_URL 직접 호출 → Next.js 프록시 경로로 변경
  • RequestModal 스팟 조작: onImageClick/addSpot/removeSpot 추가, 재탭 삭제

Test plan

  • /profile 직접 접근 시 로그인 리다이렉트 없이 프로필 표시 확인
  • Stats (Posts, Solutions, Points) 실데이터 표시 확인
  • /profile/[userId] 타인 프로필에서 FollowButton 동작
  • Profile Edit → 아바타 파일 업로드 동작
  • Style DNA Edit 모달 → 키워드/컬러 저장
  • /rankings 페이지 로드 확인
  • Upload 모달 → 이미지 탭으로 스팟 추가/삭제

Closes #46

🤖 Generated with Claude Code

thxforall and others added 15 commits April 9, 2026 19:13
- Add SVG favicon with decoded "D" logo (brand colors)
- Add PWA manifest.ts with app metadata
- Fix html lang attribute: en → ko (consistent with global-error.tsx)
- Add favicon metadata to layout.tsx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PublicProfileClient: replace placeholder sections with actual activity
  tabs (PostsGrid, SpotsList, SolutionsList) using Supabase queries
- ProfileClient: switch from API-based ActivityItemCard to Supabase-based
  grid components (works without backend API server)
- ActivityTabs: add configurable tabs prop with PUBLIC_TABS preset
- Profile OG metadata: add avatar image, username, Korean description
- Mobile header: show user display name instead of generic "Profile"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use IF NOT EXISTS to prevent failure when columns already exist
in the database (added via Supabase migration in #58).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SmartNav: uncomment Upload nav item (was hidden for 1st release #35)
- MobileNavBar: add Upload icon between Search and Explore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avatar click now shows dropdown with:
- User info (display name, username)
- Profile link
- Upload link
- Logout button (red)

Closes on outside click and route change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add bg-black/60 to container for instant backdrop
- Use fromTo with immediateRender to prevent opacity:0 flash
- Faster, smoother animation (0.2s backdrop, 0.25s modal)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Upload button now opens RequestModal via state instead of navigating
to /request/upload (intercepting route). This prevents the hero
section from re-rendering and flickering when the modal opens.

- Desktop nav Upload: button → RequestModal (no URL change)
- Profile dropdown Upload: same modal approach
- Direct URL /request/upload still works as full page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supabase defaulted to implicit grant (hash-based tokens) but the
callback route expects a code parameter for exchangeCodeForSession.
Setting flowType: 'pkce' ensures the OAuth redirect sends a code
instead of hash tokens, fixing "인증 코드가 없습니다" error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ection

The server callback route (/api/auth/callback) requires PKCE code exchange
but @supabase/auth-helpers-nextjs v0.15 doesn't handle code verifier cookies.

Fix: redirect OAuth back to the client page instead of server callback.
Supabase JS client with detectSessionInUrl: true auto-detects the hash
tokens and sets the session via onAuthStateChange.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ankings

Backend (Rust):
- Fix get_user_stats: real COUNT queries for posts/comments/likes
- Fix list_user_activities: UNION ALL across posts/spots/solutions
- Add follow/unfollow/follow-status endpoints
- Add FollowStatusResponse DTO

Frontend (Next.js):
- Add follow proxy routes and hooks (useFollowUser/useUnfollowUser/useFollowStatus)
- Add FollowButton component with Follow/Following/Unfollow states
- Integrate FollowButton into PublicProfileClient
- Avatar upload via Supabase Storage (replace URL text input)
- StyleDNAEditModal with keyword tags + color picker
- Profile OG metadata: twitter card, JSON-LD Person schema
- Rankings page with period filter (weekly/monthly/all_time)
- Rankings proxy API routes

Closes #46

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With implicit OAuth, session lives in localStorage (not cookies),
so proxy.ts middleware cannot detect it. Let /profile and /request
routes through and rely on client-side 401 → login redirect instead.

Also add isAuthReady guard to useMe/useUserStats to prevent race
condition on direct /profile navigation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pabase URL

NEXT_PUBLIC_API_BASE_URL was bypassing the proxy and hitting
Supabase URL directly, causing CORS errors. Use empty baseURL
to route through /api/v1/* proxy like all other API calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The modal's DetectionView was missing the onImageClick handler,
so users couldn't tap to add spot markers. Now uses addSpot from
requestStore, matching the page version behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add onImageClick handler to DetectionView in modal (tap to add spots)
- Add removeSpot with Trash2 icon to each detected item card
- Matches page version (/request/upload) behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a spot on the image is already selected, tapping it again
now removes it. This matches the expected UX of direct spot
management on the image without needing to scroll to the trash icon.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
decoded-app Ready Ready Preview, Comment Apr 9, 2026 11:45am

Keep FollowButton, OG metadata, and twitter card additions
from feature branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@thxforall thxforall merged commit abbd11f into dev Apr 9, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in decoded-monorepo Apr 9, 2026
@thxforall thxforall deleted the feature/46-profile-completion branch April 9, 2026 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant